Skip to content

Commit 2045055

Browse files
committed
Add GUIDE section for v3 docs
1 parent a348e83 commit 2045055

31 files changed

Lines changed: 2157 additions & 519 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ packlib_files.txt
5252
/node_modules/
5353
/docs/.vitepress/dist/
5454
/docs/.vitepress/cache/
55+
/docs/.vitepress/ext-data.json
5556
package-lock.json
5657
pnpm-lock.yaml
5758

docs/.vitepress/components/CliGenerator.vue

Lines changed: 202 additions & 381 deletions
Large diffs are not rendered by default.
Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,46 @@
11
<template>
22
<div>
3-
<header class="DocSearch-SearchBar" style="padding: 0">
4-
<form class="DocSearch-Form searchinput">
5-
<input class="DocSearch-Input" v-model="filterText" placeholder="Filter name..." @input="doFilter" />
6-
</form>
7-
</header>
8-
<table>
9-
<thead>
10-
<tr>
11-
<th>Extension Name</th>
12-
<th>Linux</th>
13-
<th>macOS</th>
14-
<th>FreeBSD</th>
15-
<th>Windows</th>
16-
</tr>
17-
</thead>
18-
<tbody>
19-
<tr v-for="item in filterData">
20-
<td v-if="!item.notes">{{ item.name }}</td>
21-
<td v-else>
22-
<a :href="'./extension-notes.html#' + item.name">{{ item.name }}</a>
23-
</td>
24-
<td>{{ item.linux }}</td>
25-
<td>{{ item.macos }}</td>
26-
<td>{{ item.freebsd }}</td>
27-
<td>{{ item.windows }}</td>
28-
</tr>
29-
</tbody>
30-
</table>
31-
<div v-if="filterData.length === 0" style="margin: 0 4px 20px 4px; color: var(--vp-c-text-2); font-size: 14px">
32-
No result, please try another keyword.
3+
<div v-if="missing" class="warning custom-block" style="margin-bottom: 16px">
4+
<p class="custom-block-title">WARNING</p>
5+
<p>Extension list is not generated yet. Run <code>bin/spc dev:gen-ext-docs</code> to generate it.</p>
336
</div>
7+
<template v-else>
8+
<header class="DocSearch-SearchBar" style="padding: 0">
9+
<form class="DocSearch-Form searchinput">
10+
<input class="DocSearch-Input" v-model="filterText" placeholder="Filter name..." @input="doFilter" />
11+
</form>
12+
</header>
13+
<table>
14+
<thead>
15+
<tr>
16+
<th>Extension Name</th>
17+
<th>Linux</th>
18+
<th>macOS</th>
19+
<th>Windows</th>
20+
<th>Website</th>
21+
</tr>
22+
</thead>
23+
<tbody>
24+
<tr v-for="item in filterData" :key="item.name">
25+
<td>
26+
<span v-if="!item.hasNotes">{{ item.name }}</span>
27+
<a v-else :href="'./extension-notes.html#' + item.name">{{ item.name }}</a>
28+
</td>
29+
<td>{{ item.linux ? '✅' : '' }}</td>
30+
<td>{{ item.macos ? '✅' : '' }}</td>
31+
<td>{{ item.windows ? '✅' : '' }}</td>
32+
<td>
33+
<a v-if="item.url" :href="item.url" target="_blank" rel="noopener noreferrer" class="ext-source-link">
34+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="currentColor"><path d="M10 6v2H5v11h11v-5h2v6a1 1 0 01-1 1H4a1 1 0 01-1-1V7a1 1 0 011-1h6zm11-3v8h-2V6.413l-7.793 7.794-1.414-1.414L17.585 5H13V3h8z"/></svg>
35+
</a>
36+
</td>
37+
</tr>
38+
</tbody>
39+
</table>
40+
<div v-if="filterData.length === 0" style="margin: 0 4px 20px 4px; color: var(--vp-c-text-2); font-size: 14px">
41+
No result, please try another keyword.
42+
</div>
43+
</template>
3444
</div>
3545
</template>
3646

@@ -41,39 +51,37 @@ export default {
4151
</script>
4252

4353
<script setup>
44-
import {ref} from "vue";
45-
import ext from '../../../config/ext.json';
54+
import { ref } from 'vue'
55+
import { data as extData } from '../extensions.data.js'
4656
47-
// 将 ext 转换为列表,方便后续操作
48-
const data = ref([]);
49-
for (const [name, item] of Object.entries(ext)) {
50-
data.value.push({
51-
name,
52-
linux: item.support?.Linux === undefined ? 'yes' : (item.support?.Linux === 'wip' ? '' : item.support?.Linux),
53-
macos: item.support?.Darwin === undefined ? 'yes' : (item.support?.Darwin === 'wip' ? '' : item.support?.Darwin),
54-
freebsd: item.support?.BSD === undefined ? 'yes' : (item.support?.BSD === 'wip' ? '' : item.support?.BSD),
55-
windows: item.support?.Windows === undefined ? 'yes' : (item.support?.Windows === 'wip' ? '' : item.support?.Windows),
56-
notes: item.notes === true,
57-
});
58-
}
59-
60-
61-
const filterData = ref(data.value);
62-
const filterText = ref('');
57+
const missing = extData.missing
58+
const data = ref(extData.extensions)
59+
const filterData = ref(extData.extensions)
60+
const filterText = ref('')
6361
6462
const doFilter = () => {
6563
if (filterText.value === '') {
66-
filterData.value = data.value;
67-
return;
64+
filterData.value = data.value
65+
return
6866
}
69-
filterData.value = data.value.filter(item => {
70-
return item.name.toLowerCase().includes(filterText.value.toLowerCase());
71-
});
67+
filterData.value = data.value.filter(item =>
68+
item.name.toLowerCase().includes(filterText.value.toLowerCase())
69+
)
7270
}
7371
</script>
7472

7573
<style>
7674
.searchinput {
7775
border: 1px solid var(--vp-c-divider);
7876
}
79-
</style>
77+
.ext-source-link {
78+
color: var(--vp-c-text-3);
79+
vertical-align: middle;
80+
opacity: 0.6;
81+
transition: opacity 0.2s;
82+
}
83+
.ext-source-link:hover {
84+
opacity: 1;
85+
color: var(--vp-c-brand-1);
86+
}
87+
</style>

docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export default {
6565
message: 'Released under the MIT License.',
6666
copyright: 'Copyright © 2023-present crazywhalecc',
6767
},
68+
externalLinkIcon: true,
6869
search: {
6970
provider: 'algolia',
7071
options: {

docs/.vitepress/extensions.data.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { readFileSync, existsSync } from 'node:fs'
2+
import { resolve, dirname } from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
5+
const __dirname = dirname(fileURLToPath(import.meta.url))
6+
const DATA_PATH = resolve(__dirname, 'ext-data.json')
7+
const NOTES_PATH = resolve(__dirname, '../en/guide/extension-notes.md')
8+
9+
export default {
10+
watch: [DATA_PATH, NOTES_PATH],
11+
12+
load() {
13+
if (!existsSync(DATA_PATH)) {
14+
console.warn(
15+
'[extensions.data.js] ext-data.json not found. ' +
16+
'Run `bin/spc dev:gen-ext-docs` to generate it.'
17+
)
18+
return { extensions: [], missing: true }
19+
}
20+
21+
const raw = JSON.parse(readFileSync(DATA_PATH, 'utf-8'))
22+
23+
// Build the set of extension names that have a section in extension-notes.md.
24+
// Headings at level 2 or 3 are matched; leading/trailing whitespace is stripped.
25+
const notesSet = new Set()
26+
if (existsSync(NOTES_PATH)) {
27+
const notesContent = readFileSync(NOTES_PATH, 'utf-8')
28+
for (const match of notesContent.matchAll(/^#{2,3}\s+(\S+)/gm)) {
29+
notesSet.add(match[1].toLowerCase())
30+
}
31+
}
32+
33+
const extensions = raw.extensions.map(ext => ({
34+
...ext,
35+
hasNotes: notesSet.has(ext.name.toLowerCase()),
36+
}))
37+
38+
return { extensions, missing: false }
39+
},
40+
}

docs/.vitepress/sidebar.en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default {
66
{ text: 'Overview', link: '/en/guide/' },
77
{ text: 'Installation', link: '/en/guide/installation' },
88
{ text: 'First Build', link: '/en/guide/first-build' },
9+
{ text: 'PHP SAPI Reference', link: '/en/guide/sapi-reference' },
910
{ text: 'CLI Reference', link: '/en/guide/cli-reference' },
1011
],
1112
},

docs/.vitepress/sidebar.zh.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default {
66
{ text: '概览', link: '/zh/guide/' },
77
{ text: '安装', link: '/zh/guide/installation' },
88
{ text: '第一次构建', link: '/zh/guide/first-build' },
9+
{ text: 'PHP SAPI 构建参考', link: '/zh/guide/sapi-reference' },
910
{ text: '命令行参考', link: '/zh/guide/cli-reference' },
1011
],
1112
},

docs/en/faq/index.md

Lines changed: 107 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,107 @@
1-
# Frequently Asked Questions
2-
3-
<!-- TODO: Categorized FAQ.
4-
Sections:
5-
- Build Issues (common compile errors, missing tools)
6-
- Extensions (dynamic loading, closed-source deps, oci8)
7-
- Windows (icon embedding, DLL loading, FFI)
8-
- Version Compatibility (PHP versions, glibc vs musl)
9-
- Source Protection (micro, encryption)
10-
Migrate and expand from v2 faq/index.md. -->
1+
# FAQ
2+
3+
Here will be some questions that you may encounter easily.
4+
5+
## What is the path of php.ini?
6+
7+
On Linux, macOS and FreeBSD, the path of `php.ini` is `/usr/local/etc/php/php.ini`.
8+
On Windows, the path is `C:\windows\php.ini` or the current directory of `php.exe`.
9+
The directory where to look for `php.ini` can be changed on *nix using the build option `--with-config-file-path`.
10+
11+
In addition, on Linux, macOS and FreeBSD, `.ini` files present in the `/usr/local/etc/php/conf.d` directory will also be loaded.
12+
On Windows, this path is empty by default.
13+
The directory can be changed using the build option `--with-config-file-scan-dir`.
14+
15+
`php.ini` will also be searched for in [the other standard locations](https://www.php.net/manual/configuration.file.php).
16+
17+
## Can statically-compiled PHP install extensions?
18+
19+
Because the principle of installing PHP extensions under the normal mode is to use `.so` type dynamic link library to install new extensions,
20+
and we use the static link PHP compiled by this project. However, static linking has different definitions in different operating systems.
21+
22+
First of all, for Linux systems, statically linked binaries will not link the system's dynamic link library.
23+
Purely statically linked binaries (`build with -all-static`) cannot load dynamic libraries, so new extensions cannot be added.
24+
At the same time, in pure static mode, you cannot use extensions such as `ffi` to load external `.so` modules.
25+
26+
You can use the command `ldd buildroot/bin/php` to check whether the binary you built under Linux is purely statically linked.
27+
28+
If you build GNU libc based PHP, you can use the `ffi` extension to load external `.so` modules and load `.so` extensions with the same ABI.
29+
30+
For example, you can use the following command to build a static PHP binary dynamically linked with glibc,
31+
supporting FFI extensions and loading the `xdebug.so` extension of the same PHP version and the same TS type:
32+
33+
```bash
34+
SPC_TARGET=native-native-gnu.2.17 spc build:php "ffi,xml" --build-cli -vvv
35+
36+
buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" --ri xdebug
37+
```
38+
39+
This uses the Zig toolchain to produce a partially static binary dynamically linked against glibc 2.17. No Docker and no extra cross-compilation toolchain are required.
40+
41+
For macOS platform, almost all binaries under macOS cannot be truly purely statically linked, and almost all binaries will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`.
42+
So on macOS, you can **directly** use SPC to build statically compiled PHP binaries with dynamically linked extensions:
43+
44+
1. Build shared extension `xxx.so` using: `--build-shared=XXX` option. e.g. `spc build:php "bcmath,zlib" --build-shared=xdebug --build-cli`
45+
2. You will get `buildroot/modules/xdebug.so` and `buildroot/bin/php`.
46+
3. The `xdebug.so` file could be used for php that version and thread-safe are the same.
47+
48+
For the Windows platform, since officially built extensions (such as `php_yaml.dll`) force the use of the `php8.dll` dynamic library as a link, and statically built PHP does not include any dynamic libraries other than system libraries,
49+
php.exe built by static-php cannot load officially built dynamic extensions. Since StaticPHP does not yet support building dynamic extensions, there is currently no way to load dynamic extensions with static-php.
50+
51+
However, Windows can normally use the `FFI` extension to load other dll files and call them.
52+
53+
## Can it support Oracle database extension?
54+
55+
Some extensions that rely on closed source libraries, such as `oci8`, `sourceguardian`, etc.,
56+
they do not provide purely statically compiled dependent library files (`.a`), only dynamic dependent library files (`.so`).
57+
These extensions cannot be compiled into StaticPHP using source code, so this project may never support these extensions.
58+
However, in theory you can access and use such extensions under macOS and Linux according to the above questions.
59+
60+
## Does it support Windows?
61+
62+
The project currently supports Windows, but the number of supported extensions is small. Windows support is not perfect. There are mainly the following problems:
63+
64+
1. The compilation process of Windows is different from that of *nix, and the toolchain used is also different. The compilation tools used to compile the dependent libraries of each extension are almost completely different.
65+
2. The demand for the Windows version will also be advanced based on the needs of all people who use this project. If many people need it, I will support related extensions as soon as possible.
66+
67+
## Can I protect my source code with micro?
68+
69+
You can't. micro.sfx is essentially combining php and php code into one file,
70+
there is no process of compiling or encrypting the PHP code.
71+
72+
First of all, php-src is the official interpreter of PHP code, and there is no PHP compiler compatible with mainstream branches on the market.
73+
I saw on the Internet that there is a project called BPC (Binary PHP Compiler?) that can compile PHP into binary,
74+
but there are many restrictions.
75+
76+
The direction of encrypting and protecting the code is not the same as compiling.
77+
After compiling, the code can also be obtained through reverse engineering and other methods.
78+
The real protection is still carried out by means of packing and encrypting the code.
79+
80+
Therefore, this project (StaticPHP) and related projects (lwmbs, swoole-cli) all provide a convenient compilation tool for php-src source code.
81+
The phpmicro referenced by this project and related projects is only a package of PHP's sapi interface, not a compilation tool for PHP code.
82+
The compiler for PHP code is a completely different project, so the extra cases are not taken into account.
83+
If you are interested in encryption, you can consider using existing encryption technologies,
84+
such as Swoole Compiler, Source Guardian, etc.
85+
86+
## Unable to use ssl
87+
88+
**Update: This issue has been fixed in the latest version of StaticPHP, which now reads the system's certificate file by default. If you still have problems, try the solution below.**
89+
90+
When using curl, pgsql, etc. to request an HTTPS website or establish an SSL connection, there may be an `error:80000002:system library::No such file or directory` error.
91+
This error is caused by statically compiled PHP without specifying `openssl.cafile` via `php.ini`.
92+
93+
You can solve this problem by specifying `php.ini` before using PHP and adding `openssl.cafile=/path/to/your-cert.pem` in the INI.
94+
95+
For Linux systems, you can download the [cacert.pem](https://curl.se/docs/caextract.html) file from the curl official website, or you can use the certificate file that comes with the system.
96+
For the certificate locations of different distros, please refer to [Golang docs](https://go.dev/src/crypto/x509/root_linux.go).
97+
98+
> INI configuration `openssl.cafile` cannot be set dynamically using the `ini_set()` function, because `openssl.cafile` is a `PHP_INI_SYSTEM` type configuration and can only be set in the `php.ini` file.
99+
100+
## Why don't we support older versions of PHP?
101+
102+
Because older versions of PHP have many problems, such as security issues, performance issues, and functional issues.
103+
In addition, many older versions of PHP are not compatible with the latest dependency libraries,
104+
which is one of the reasons why older versions of PHP are not supported.
105+
106+
You can use older versions compiled earlier by StaticPHP, such as PHP 8.0, but earlier versions will not be explicitly supported.
107+

docs/en/guide/cli-generator.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
aside: false
33
---
44

5+
<script setup>
6+
import CliGenerator from "../../.vitepress/components/CliGenerator.vue";
7+
</script>
8+
59
# Build Command Generator
610

7-
<!-- TODO: Embed CliGenerator Vue component. -->
11+
<CliGenerator lang="en" />

0 commit comments

Comments
 (0)