<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[AdminsForum - aaPanel PHP & Extensions Guides]]></title>
		<link>https://adminsforum.com/</link>
		<description><![CDATA[AdminsForum - https://adminsforum.com]]></description>
		<pubDate>Thu, 15 Oct 2026 06:11:14 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[Fix open_basedir Restriction Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-open-basedir-restriction-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 13:55:15 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-open-basedir-restriction-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">“open_basedir restriction in effect” identifies a PHP filesystem access attempt outside the configured allowed paths. Find the attempted path and why the application uses it before changing permissions or disabling a restriction.</span><br />
<br />
This guide demonstrates a blocked read and a successful read from an appropriate location with the same restriction still enabled. It complements the guides for PHP script-path, session-storage and permission errors; those symptoms can look similar but require different evidence.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=329" target="_blank" title="">php-basedir-20261015.jpg</a> (Size: 134.22 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Find the complete warning in the website logs</span><br />
Record the failing action, request path, time and timezone. In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected website and select <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Match the request in the access log. Panel labels can vary by version.<br />
<br />
Our lab site's normal website error log is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log</code></div></div>Use your actual domain and configured path. An optional bounded SSH check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Keep public error display off. Share only a short redacted excerpt: filenames can contain private account names or application details.<br />
<br />
Our private test captured this shortened warning:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>file_get_contents(): open_basedir restriction in effect.
File(...outside...) is not within the allowed path(s): (...scope...)</code></div></div>The useful evidence is the attempted file, allowed scope and code location. A generic “Failed to open stream” message without the preceding cause is less informative.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Distinguish a restriction from other filesystem problems</span><br />
A path restriction can reject an otherwise existing and readable file. Changing it to mode 777 does not put it inside the allowed scope. Conversely, a file inside the scope can still fail because it is missing, permissions are wrong, storage is full or the filesystem is read-only.<br />
<br />
Read the specific warning rather than changing several controls at once. If the log says Permission denied or No such file or directory without a matching restriction warning, investigate that evidence separately. A 500 response alone does not prove open_basedir is responsible.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Confirm the setting in the website's PHP context</span><br />
Identify the PHP version selected for the affected site. CLI PHP can have a different configuration from PHP-FPM. In a protected diagnostic context for that request, inspect:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP_VERSION
PHP_SAPI
ini_get('open_basedir')</code></div></div>These are diagnostic expressions, not a public endpoint to leave online. Do not upload a full phpinfo page or print private application paths to visitors.<br />
<br />
Review the setting's effective source: the panel's site configuration, PHP-FPM pool, applicable per-directory files and application startup code can all matter. A saved value in one file does not prove that it is the active value for the failing request. Inspect before editing; do not delete panel-managed files as a shortcut.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Work out why the application chose that location</span><br />
Check whether a deployment moved to a new directory, a plugin retained an old absolute path or a temporary/cache directory points outside the intended layout. Compare application configuration with the actual files and public document root.<br />
<br />
For an illustrative application:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Application files: /www/wwwroot/example.com/app
Public web root:   /www/wwwroot/example.com/app/public
Private data:      /www/wwwroot/example.com/app/storage</code></div></div>These are examples, not a tested deployment recipe. Follow your application's requirements and hosting isolation model. Private storage should not be moved into a publicly served directory merely to make a read succeed.<br />
<br />
Resolve the actual target of symlinks as part of the review. A familiar-looking path can refer to another location. Do not use symlinks or command execution to bypass the restriction.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What the private lab test demonstrated</span><br />
We used the installed PHP-FPM service through a separate Nginx endpoint bound only to loopback. The fixture applied and verified a request-local allowed directory. Two harmless text fixtures contained identical data; one was inside that scope and one outside.<br />
<ul class="mycode_list"><li>The outside read failed and produced the exact open_basedir warning. The test script explicitly returned <span style="font-weight: bold;" class="mycode_b">HTTP 500</span> when the read failed.<br />
</li>
<li>A second request read the inside fixture and returned <span style="font-weight: bold;" class="mycode_b">HTTP 200</span> with the expected data. Its response confirmed the restriction remained enabled.<br />
</li>
<li>No new matching restriction warning appeared after the successful request.<br />
</li>
</ul>
The 500 was our fixture's explicit error handling, not a promise that every PHP restriction warning automatically returns 500. We did not move real application data, broaden a production allowlist or test a complete application repair.<br />
<br />
All disposable PHP and text fixtures were removed, the private directory removed and the listener stopped. Its PID file disappeared. Hash checks confirmed the main Nginx configuration, PHP-FPM pool configuration and php.ini were unchanged. The normal HTTPS site returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Correct the demonstrated path mismatch</span><br />
Prefer correcting an unintended application path or using an appropriate existing private storage location when the application supports it. Back up configuration and data before any real move. Confirm ownership, read/write requirements and the application setting that points to the location.<br />
<br />
If the application genuinely requires another private directory, review that requirement with the site's isolation design and configuration owner before considering a narrowly scoped allowlist change. Do not allow the filesystem root, other websites or a large parent directory just to silence one warning.<br />
<br />
Record the previous value and affected sites. Validate any server configuration edit before applying it, and verify the effective PHP value afterward. Keep a rollback path. Do not globally disable the panel's path restriction as the first troubleshooting step.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Keep the limits of this protection clear</span><br />
PHP documents open_basedir as an additional safeguard, not comprehensive isolation. Keep proper service-account permissions and the hosting environment's other isolation controls in place. Our two-file test demonstrates ordinary PHP file access behavior; it is not a security audit or proof that one PHP setting isolates untrusted tenants.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify the application, not only the status code</span><br />
Repeat one safe version of the original action with representative data. Confirm the intended result, inspect new logs and verify the required read or write actually completed. A 200 response alone can contain an application-level error.<br />
<br />
Check that private files remain outside the public document root and that unrelated sites were not affected by a shared setting. Remove temporary diagnostics. If the error persists, retain the redacted warning and review the exact path instead of repeatedly widening access.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request, include</span><br />
The PHP version and SAPI, failing action, timestamp, redacted attempted path and allowed scope, and relevant recent deployment changes. Exclude credentials, private file contents and complete configuration dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-fix-primary-script-unknown-php-errors-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Trace PHP script-filename mismatches</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-session-storage-errors-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Diagnose PHP session-storage errors</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical reference</span><br />
<a href="https://www.php.net/manual/en/ini.core.php#ini.open-basedir" target="_blank" rel="noopener" class="mycode_url">PHP open_basedir behavior and security limits</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">“open_basedir restriction in effect” identifies a PHP filesystem access attempt outside the configured allowed paths. Find the attempted path and why the application uses it before changing permissions or disabling a restriction.</span><br />
<br />
This guide demonstrates a blocked read and a successful read from an appropriate location with the same restriction still enabled. It complements the guides for PHP script-path, session-storage and permission errors; those symptoms can look similar but require different evidence.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=329" target="_blank" title="">php-basedir-20261015.jpg</a> (Size: 134.22 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Find the complete warning in the website logs</span><br />
Record the failing action, request path, time and timezone. In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected website and select <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Match the request in the access log. Panel labels can vary by version.<br />
<br />
Our lab site's normal website error log is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log</code></div></div>Use your actual domain and configured path. An optional bounded SSH check is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Keep public error display off. Share only a short redacted excerpt: filenames can contain private account names or application details.<br />
<br />
Our private test captured this shortened warning:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>file_get_contents(): open_basedir restriction in effect.
File(...outside...) is not within the allowed path(s): (...scope...)</code></div></div>The useful evidence is the attempted file, allowed scope and code location. A generic “Failed to open stream” message without the preceding cause is less informative.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Distinguish a restriction from other filesystem problems</span><br />
A path restriction can reject an otherwise existing and readable file. Changing it to mode 777 does not put it inside the allowed scope. Conversely, a file inside the scope can still fail because it is missing, permissions are wrong, storage is full or the filesystem is read-only.<br />
<br />
Read the specific warning rather than changing several controls at once. If the log says Permission denied or No such file or directory without a matching restriction warning, investigate that evidence separately. A 500 response alone does not prove open_basedir is responsible.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Confirm the setting in the website's PHP context</span><br />
Identify the PHP version selected for the affected site. CLI PHP can have a different configuration from PHP-FPM. In a protected diagnostic context for that request, inspect:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP_VERSION
PHP_SAPI
ini_get('open_basedir')</code></div></div>These are diagnostic expressions, not a public endpoint to leave online. Do not upload a full phpinfo page or print private application paths to visitors.<br />
<br />
Review the setting's effective source: the panel's site configuration, PHP-FPM pool, applicable per-directory files and application startup code can all matter. A saved value in one file does not prove that it is the active value for the failing request. Inspect before editing; do not delete panel-managed files as a shortcut.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Work out why the application chose that location</span><br />
Check whether a deployment moved to a new directory, a plugin retained an old absolute path or a temporary/cache directory points outside the intended layout. Compare application configuration with the actual files and public document root.<br />
<br />
For an illustrative application:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Application files: /www/wwwroot/example.com/app
Public web root:   /www/wwwroot/example.com/app/public
Private data:      /www/wwwroot/example.com/app/storage</code></div></div>These are examples, not a tested deployment recipe. Follow your application's requirements and hosting isolation model. Private storage should not be moved into a publicly served directory merely to make a read succeed.<br />
<br />
Resolve the actual target of symlinks as part of the review. A familiar-looking path can refer to another location. Do not use symlinks or command execution to bypass the restriction.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What the private lab test demonstrated</span><br />
We used the installed PHP-FPM service through a separate Nginx endpoint bound only to loopback. The fixture applied and verified a request-local allowed directory. Two harmless text fixtures contained identical data; one was inside that scope and one outside.<br />
<ul class="mycode_list"><li>The outside read failed and produced the exact open_basedir warning. The test script explicitly returned <span style="font-weight: bold;" class="mycode_b">HTTP 500</span> when the read failed.<br />
</li>
<li>A second request read the inside fixture and returned <span style="font-weight: bold;" class="mycode_b">HTTP 200</span> with the expected data. Its response confirmed the restriction remained enabled.<br />
</li>
<li>No new matching restriction warning appeared after the successful request.<br />
</li>
</ul>
The 500 was our fixture's explicit error handling, not a promise that every PHP restriction warning automatically returns 500. We did not move real application data, broaden a production allowlist or test a complete application repair.<br />
<br />
All disposable PHP and text fixtures were removed, the private directory removed and the listener stopped. Its PID file disappeared. Hash checks confirmed the main Nginx configuration, PHP-FPM pool configuration and php.ini were unchanged. The normal HTTPS site returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Correct the demonstrated path mismatch</span><br />
Prefer correcting an unintended application path or using an appropriate existing private storage location when the application supports it. Back up configuration and data before any real move. Confirm ownership, read/write requirements and the application setting that points to the location.<br />
<br />
If the application genuinely requires another private directory, review that requirement with the site's isolation design and configuration owner before considering a narrowly scoped allowlist change. Do not allow the filesystem root, other websites or a large parent directory just to silence one warning.<br />
<br />
Record the previous value and affected sites. Validate any server configuration edit before applying it, and verify the effective PHP value afterward. Keep a rollback path. Do not globally disable the panel's path restriction as the first troubleshooting step.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Keep the limits of this protection clear</span><br />
PHP documents open_basedir as an additional safeguard, not comprehensive isolation. Keep proper service-account permissions and the hosting environment's other isolation controls in place. Our two-file test demonstrates ordinary PHP file access behavior; it is not a security audit or proof that one PHP setting isolates untrusted tenants.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify the application, not only the status code</span><br />
Repeat one safe version of the original action with representative data. Confirm the intended result, inspect new logs and verify the required read or write actually completed. A 200 response alone can contain an application-level error.<br />
<br />
Check that private files remain outside the public document root and that unrelated sites were not affected by a shared setting. Remove temporary diagnostics. If the error persists, retain the redacted warning and review the exact path instead of repeatedly widening access.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">For a support request, include</span><br />
The PHP version and SAPI, failing action, timestamp, redacted attempted path and allowed scope, and relevant recent deployment changes. Exclude credentials, private file contents and complete configuration dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-fix-primary-script-unknown-php-errors-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Trace PHP script-filename mismatches</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-session-storage-errors-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Diagnose PHP session-storage errors</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical reference</span><br />
<a href="https://www.php.net/manual/en/ini.core.php#ini.open-basedir" target="_blank" rel="noopener" class="mycode_url">PHP open_basedir behavior and security limits</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix PHP Session Storage Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-php-session-storage-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 13:42:13 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-php-session-storage-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">If a PHP site loses session state or sends users back to login, check its session handler, storage and cookie behavior. A session-storage warning is evidence to investigate; a login loop alone does not prove the storage directory is wrong.</span><br />
<br />
This guide reproduces one file-session failure in a private aaPanel lab. It then verifies that state survives across two requests. It does not test a real login, reset passwords or change any production session settings.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=327" target="_blank" title="">php-session-20261015.jpg</a> (Size: 130.61 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, formatted as a transcript rather than a screenshot. No session identifiers or cookie values are shown.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the symptom and inspect the logs</span><br />
Note the time and timezone, URL path, action and whether the issue affects one browser or many users. Did it begin after a deployment, PHP-version change, directory cleanup or proxy change? Avoid repeated submissions that can modify data.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and select <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Match the request with the access log. Labels can vary by panel version. On our lab site's normal website, the error-log path is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log</code></div></div>Use the path configured for your own site. A bounded SSH example is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Keep errors logged privately rather than enabling public error display. Session identifiers can appear in filenames inside warnings; redact them before posting logs.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Read the specific session warning</span><br />
Our private test used a deliberately nonexistent save directory and produced these shortened, redacted messages:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>session_start(): open(.../sess_[REDACTED], O_RDWR) failed:
No such file or directory

session_start(): Failed to read session data: files</code></div></div>That evidence pointed to the test's missing directory. A permission-denied warning instead requires an access check. Disk-full, inode exhaustion and a read-only filesystem require different checks. Do not treat all session failures as the same problem.<br />
<br />
A session_start warning does not automatically mean PHP returns HTTP 500. Our test fixture explicitly chose 500 when session_start returned false. Real applications can handle the failure differently or display an unrelated error page.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Confirm the website's active session configuration</span><br />
Confirm the site's PHP version in aaPanel. A command-line PHP process can use different settings from PHP-FPM, and an application can override session behavior before starting a session.<br />
<br />
In a protected diagnostic context for the relevant request, inspect:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP_VERSION
PHP_SAPI
ini_get('session.save_handler')
session_save_path()</code></div></div>These expressions are diagnostic aids, not a public page to leave online. Do not print the session ID, session contents, cookies or a full phpinfo dump.<br />
<br />
For the files handler, the save path identifies filesystem storage. Other handlers, such as a configured Redis or custom application handler, need their own connectivity and application checks. Creating a local folder cannot fix a remote handler's authentication or availability problem.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Check the intended directory and service account</span><br />
For a files-based setup, verify that the effective path exists and the PHP-FPM worker can traverse its parent directories and read and write the intended session storage. The correct account may differ from your SSH user and from the web server's worker account.<br />
<br />
Inspect the actual deployment ownership before changing it. Do not recursively apply 777 permissions or change the ownership of all website and session directories. Session storage should be private and outside the public document root. A shared world-readable directory is not a suitable generic repair.<br />
<br />
If a pool uses a filesystem jail or path restrictions, check how the path is seen by that pool. Investigate a specific open_basedir message without disabling the protection globally. Also check space, free inodes and filesystem state when the warning points to storage failure.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our private test demonstrated</span><br />
We used the installed PHP-FPM service through a separate loopback-only Nginx endpoint. The harmless fixture selected the files handler and request-local storage settings; no shared php.ini or pool configuration was changed.<br />
<ul class="mycode_list"><li>With the deliberately missing directory, session_start failed, warnings appeared in the private log and our fixture explicitly returned <span style="font-weight: bold;" class="mycode_b">500</span>.<br />
</li>
<li>With a disposable directory owned by the lab PHP worker account and mode <span style="font-weight: bold;" class="mycode_b">0700</span>, a request returned <span style="font-weight: bold;" class="mycode_b">200</span> and stored counter <span style="font-weight: bold;" class="mycode_b">1</span>.<br />
</li>
<li>A second request reused the same private test cookie and returned <span style="font-weight: bold;" class="mycode_b">200</span> with counter <span style="font-weight: bold;" class="mycode_b">2</span>. One test session file existed, confirming persistence across those requests.<br />
</li>
</ul>
Mode 0700 matched this isolated single-account test; it is not a blanket instruction for every hosting layout. The fixture used loopback HTTP only and was not an HTTPS or browser-cookie security test.<br />
<br />
The cookie jar, disposable session files, private directory and PHP fixture were removed afterward. The private listener stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration, PHP-FPM pool configuration and php.ini were unchanged. The normal HTTPS site returned 200.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. If storage works, investigate the cookie and application flow</span><br />
In the browser's Network and storage tools, confirm the application sets the intended cookie and that the next relevant request sends it back. Review the hostname, cookie domain, path, expiry and browser rejection reason. A move between hostnames or an incorrect HTTPS/proxy interpretation can change behavior.<br />
<br />
Do not weaken Secure, HttpOnly or SameSite protections simply to make a test pass. Correct the demonstrated deployment or application mismatch while preserving the intended security model. Never post raw cookie values or authenticated network captures publicly.<br />
<br />
If the same cookie is returned but state disappears, inspect the application's handler, expiry and cleanup behavior. Multiple backend servers need a session design that keeps a user's state available across requests. A fresh browser test is useful, but clearing cookies can hide a server-side issue rather than resolve it.<br />
<br />
Login loops can also come from application redirects, authentication logic, CSRF handling or incorrect caching. Do not cache private authenticated responses in a shared public cache. Our counter test did not validate any real application's authentication flow.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply a narrow correction and verify persistence</span><br />
Back up the relevant configuration and record the old value and scope. Correct the demonstrated path, deployment access or application setting through the supported workflow. Determine whether a PHP setting change affects other sites on the same PHP version before applying it.<br />
<br />
Use a controlled test account and perform one safe sign-in. Confirm the intended next page and a later request retain the correct state, then test sign-out. Check for new matching log warnings. Do not rely on one HTTP 200 response as proof that authentication works.<br />
<br />
Keep a rollback path if a configuration change causes other sites to lose sessions. Remove temporary diagnostics and do not delete live session files as a troubleshooting shortcut; that can sign users out and destroy evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">When requesting help</span><br />
Provide the PHP version, handler type, time, short redacted warning and recent deployment changes. Describe whether the browser returns the expected cookie without revealing its value. Keep session contents and user data private.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Locate website logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<a href="https://adminsforum.com/Thread-guide-linux-disk-full-diagnose-space-and-inodes-before-deleting-files" target="_blank" rel="noopener" class="mycode_url">Diagnose storage and inode problems</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://www.php.net/manual/en/session.configuration.php" target="_blank" rel="noopener" class="mycode_url">PHP session configuration</a><br />
<a href="https://www.php.net/manual/en/function.session-start.php" target="_blank" rel="noopener" class="mycode_url">PHP session_start behavior</a><br />
<a href="https://www.php.net/manual/en/session.examples.basic.php" target="_blank" rel="noopener" class="mycode_url">PHP session persistence basics</a><br />
<a href="https://www.php.net/manual/en/session.security.ini.php" target="_blank" rel="noopener" class="mycode_url">PHP session security settings</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">If a PHP site loses session state or sends users back to login, check its session handler, storage and cookie behavior. A session-storage warning is evidence to investigate; a login loop alone does not prove the storage directory is wrong.</span><br />
<br />
This guide reproduces one file-session failure in a private aaPanel lab. It then verifies that state survives across two requests. It does not test a real login, reset passwords or change any production session settings.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=327" target="_blank" title="">php-session-20261015.jpg</a> (Size: 130.61 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, formatted as a transcript rather than a screenshot. No session identifiers or cookie values are shown.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the symptom and inspect the logs</span><br />
Note the time and timezone, URL path, action and whether the issue affects one browser or many users. Did it begin after a deployment, PHP-version change, directory cleanup or proxy change? Avoid repeated submissions that can modify data.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and select <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Match the request with the access log. Labels can vary by panel version. On our lab site's normal website, the error-log path is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log</code></div></div>Use the path configured for your own site. A bounded SSH example is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Keep errors logged privately rather than enabling public error display. Session identifiers can appear in filenames inside warnings; redact them before posting logs.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Read the specific session warning</span><br />
Our private test used a deliberately nonexistent save directory and produced these shortened, redacted messages:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>session_start(): open(.../sess_[REDACTED], O_RDWR) failed:
No such file or directory

session_start(): Failed to read session data: files</code></div></div>That evidence pointed to the test's missing directory. A permission-denied warning instead requires an access check. Disk-full, inode exhaustion and a read-only filesystem require different checks. Do not treat all session failures as the same problem.<br />
<br />
A session_start warning does not automatically mean PHP returns HTTP 500. Our test fixture explicitly chose 500 when session_start returned false. Real applications can handle the failure differently or display an unrelated error page.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Confirm the website's active session configuration</span><br />
Confirm the site's PHP version in aaPanel. A command-line PHP process can use different settings from PHP-FPM, and an application can override session behavior before starting a session.<br />
<br />
In a protected diagnostic context for the relevant request, inspect:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP_VERSION
PHP_SAPI
ini_get('session.save_handler')
session_save_path()</code></div></div>These expressions are diagnostic aids, not a public page to leave online. Do not print the session ID, session contents, cookies or a full phpinfo dump.<br />
<br />
For the files handler, the save path identifies filesystem storage. Other handlers, such as a configured Redis or custom application handler, need their own connectivity and application checks. Creating a local folder cannot fix a remote handler's authentication or availability problem.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Check the intended directory and service account</span><br />
For a files-based setup, verify that the effective path exists and the PHP-FPM worker can traverse its parent directories and read and write the intended session storage. The correct account may differ from your SSH user and from the web server's worker account.<br />
<br />
Inspect the actual deployment ownership before changing it. Do not recursively apply 777 permissions or change the ownership of all website and session directories. Session storage should be private and outside the public document root. A shared world-readable directory is not a suitable generic repair.<br />
<br />
If a pool uses a filesystem jail or path restrictions, check how the path is seen by that pool. Investigate a specific open_basedir message without disabling the protection globally. Also check space, free inodes and filesystem state when the warning points to storage failure.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our private test demonstrated</span><br />
We used the installed PHP-FPM service through a separate loopback-only Nginx endpoint. The harmless fixture selected the files handler and request-local storage settings; no shared php.ini or pool configuration was changed.<br />
<ul class="mycode_list"><li>With the deliberately missing directory, session_start failed, warnings appeared in the private log and our fixture explicitly returned <span style="font-weight: bold;" class="mycode_b">500</span>.<br />
</li>
<li>With a disposable directory owned by the lab PHP worker account and mode <span style="font-weight: bold;" class="mycode_b">0700</span>, a request returned <span style="font-weight: bold;" class="mycode_b">200</span> and stored counter <span style="font-weight: bold;" class="mycode_b">1</span>.<br />
</li>
<li>A second request reused the same private test cookie and returned <span style="font-weight: bold;" class="mycode_b">200</span> with counter <span style="font-weight: bold;" class="mycode_b">2</span>. One test session file existed, confirming persistence across those requests.<br />
</li>
</ul>
Mode 0700 matched this isolated single-account test; it is not a blanket instruction for every hosting layout. The fixture used loopback HTTP only and was not an HTTPS or browser-cookie security test.<br />
<br />
The cookie jar, disposable session files, private directory and PHP fixture were removed afterward. The private listener stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration, PHP-FPM pool configuration and php.ini were unchanged. The normal HTTPS site returned 200.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. If storage works, investigate the cookie and application flow</span><br />
In the browser's Network and storage tools, confirm the application sets the intended cookie and that the next relevant request sends it back. Review the hostname, cookie domain, path, expiry and browser rejection reason. A move between hostnames or an incorrect HTTPS/proxy interpretation can change behavior.<br />
<br />
Do not weaken Secure, HttpOnly or SameSite protections simply to make a test pass. Correct the demonstrated deployment or application mismatch while preserving the intended security model. Never post raw cookie values or authenticated network captures publicly.<br />
<br />
If the same cookie is returned but state disappears, inspect the application's handler, expiry and cleanup behavior. Multiple backend servers need a session design that keeps a user's state available across requests. A fresh browser test is useful, but clearing cookies can hide a server-side issue rather than resolve it.<br />
<br />
Login loops can also come from application redirects, authentication logic, CSRF handling or incorrect caching. Do not cache private authenticated responses in a shared public cache. Our counter test did not validate any real application's authentication flow.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply a narrow correction and verify persistence</span><br />
Back up the relevant configuration and record the old value and scope. Correct the demonstrated path, deployment access or application setting through the supported workflow. Determine whether a PHP setting change affects other sites on the same PHP version before applying it.<br />
<br />
Use a controlled test account and perform one safe sign-in. Confirm the intended next page and a later request retain the correct state, then test sign-out. Check for new matching log warnings. Do not rely on one HTTP 200 response as proof that authentication works.<br />
<br />
Keep a rollback path if a configuration change causes other sites to lose sessions. Remove temporary diagnostics and do not delete live session files as a troubleshooting shortcut; that can sign users out and destroy evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">When requesting help</span><br />
Provide the PHP version, handler type, time, short redacted warning and recent deployment changes. Describe whether the browser returns the expected cookie without revealing its value. Keep session contents and user data private.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Locate website logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<a href="https://adminsforum.com/Thread-guide-linux-disk-full-diagnose-space-and-inodes-before-deleting-files" target="_blank" rel="noopener" class="mycode_url">Diagnose storage and inode problems</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://www.php.net/manual/en/session.configuration.php" target="_blank" rel="noopener" class="mycode_url">PHP session configuration</a><br />
<a href="https://www.php.net/manual/en/function.session-start.php" target="_blank" rel="noopener" class="mycode_url">PHP session_start behavior</a><br />
<a href="https://www.php.net/manual/en/session.examples.basic.php" target="_blank" rel="noopener" class="mycode_url">PHP session persistence basics</a><br />
<a href="https://www.php.net/manual/en/session.security.ini.php" target="_blank" rel="noopener" class="mycode_url">PHP session security settings</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix PHP Memory Exhausted Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-php-memory-exhausted-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 13:31:17 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-php-memory-exhausted-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">“Allowed memory size exhausted” means a PHP allocation hit the applicable memory limit. Confirm the fatal error and the website's active PHP settings before raising a limit: the real cause may be a large batch, a plugin, an image operation or inefficient code.</span><br />
<br />
This guide focuses on diagnosis and verification. The separate upload-and-memory-settings guide explains basic setting changes; an upload-size limit is not the same as the amount of memory an application needs while processing a request.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=325" target="_blank" title="">php-memory-20261015.jpg</a> (Size: 129.22 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Find the matching fatal error</span><br />
Record the failing action, URL path and time with timezone. Was it an import, export, image conversion, admin page or ordinary visit? Repeat only a safe action; an operation can have side effects before it fails.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the site and select <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Match the entry with the access log. On our lab the website error file is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log</code></div></div>Use your own configured domain and path. If PHP sends errors elsewhere, inspect the active PHP error-log destination and application logs too. Keep display_errors off on a public site; diagnose from private logs rather than exposing paths and stack traces to visitors.<br />
<br />
Our isolated PHP-FPM request produced:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP Fatal error: Allowed memory size of 16777216 bytes exhausted
(tried to allocate 33554464 bytes)</code></div></div>The allowed amount was 16 MiB. The attempted allocation is the size of a particular allocation attempt, not the application's total memory requirement. Do not add the two numbers and assume that is a reliable production setting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the PHP version and settings used by the website</span><br />
Confirm the site's selected PHP version in aaPanel first. The PHP executable used in SSH or a scheduled job can load different settings from PHP-FPM. Editing a CLI configuration does not prove the website changed.<br />
<br />
In a private diagnostic context within the relevant application request, useful values include:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP_VERSION
PHP_SAPI
php_ini_loaded_file()
ini_get('memory_limit')
memory_get_peak_usage(true)</code></div></div>These are diagnostic expressions, not a complete public endpoint to upload. Prefer temporary protected diagnostics or private application logging, and remove them when finished. A full phpinfo page reveals much more information than this investigation needs.<br />
<br />
Check for application overrides, per-directory configuration and PHP-FPM pool settings. If a pool administrator has locked a setting, an application-level change may not take effect. Verify the final value in the failing execution context rather than assuming a saved panel value wins.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. What our private PHP-FPM test showed</span><br />
We used a harmless PHP fixture outside the public website root and a separate loopback-only Nginx endpoint. The script applied and checked a <span style="font-weight: bold;" class="mycode_b">request-local 16M memory limit</span>; no shared php.ini or PHP-FPM pool setting was changed.<br />
<ul class="mycode_list"><li>A bulk attempt to create a 32 MiB string returned <span style="font-weight: bold;" class="mycode_b">HTTP 500</span>. The private Nginx error log captured the PHP memory fatal error.<br />
</li>
<li>A second request created and discarded thirty-two 1 MiB strings, one at a time. It counted <span style="font-weight: bold;" class="mycode_b">33,554,432 synthetic bytes</span> and returned <span style="font-weight: bold;" class="mycode_b">HTTP 200</span> under the same 16M limit.<br />
</li>
<li>The successful request identified its SAPI as <span style="font-weight: bold;" class="mycode_b">fpm-fcgi</span> and reported a peak PHP allocation of <span style="font-weight: bold;" class="mycode_b">2,097,152 bytes</span>. No new matching memory fatal appeared after it.<br />
</li>
</ul>
This was a synthetic allocation comparison. It did not read, validate or transform a real import, and it does not prove every application can be converted to chunked processing. It shows why total data handled and peak live allocation are different questions.<br />
<br />
The PHP fixture was removed, the private listener stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration, PHP-FPM pool configuration and php.ini were unchanged. The normal HTTPS site returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Investigate why this request needs so much memory</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Imports and exports:</span> check whether the application loads a whole file or result set into an array. Supported batching or streaming may reduce peak allocation; maintain correct validation, transaction handling and resumability.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Image processing:</span> compressed file size does not describe the memory needed for decoded pixels and transformations. Review image dimensions, format, library and concurrent jobs.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Plugins or recent changes:</span> compare the incident with deployment history and a controlled staging reproduction. Do not disable unrelated production features randomly.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Database results:</span> inspect how many rows and columns the application fetches and retains. A faster SQL query can still return an excessively large result.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Repeated growth:</span> check code that accumulates arrays, cached objects or repeated copies. The line reporting failure is where the next allocation failed, not necessarily where all earlier memory was consumed.<br />
</li>
</ul>
Collect evidence for one representative failing action before changing multiple settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Distinguish PHP exhaustion from a server OOM event</span><br />
A PHP memory fatal is not proof that the entire VPS ran out of RAM. An operating-system or container memory kill is a different event and needs system-level evidence. Check the incident time against available memory, swap activity and system or service logs.<br />
<br />
PHP's own peak-allocation report is not the complete operating-system memory footprint of a worker. Extensions, shared allocations and other process overhead can make a worker's footprint larger. Do not size PHP-FPM concurrency using memory_limit alone.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. When a finite limit increase is justified</span><br />
Sometimes a legitimate operation needs more memory after application checks. Back up the relevant configuration, record the old value and scope, and review available headroom with the database and other services running.<br />
<br />
In aaPanel open the installed PHP version used by the site, then locate its configuration or limit settings. Panel labels vary. Determine whether the change affects every site on that PHP version or only the intended application. Apply the smallest measured finite change through the supported panel workflow and reload the relevant service if required.<br />
<br />
Avoid memory_limit=-1 as a blanket repair. Increasing per-request allowances alongside many PHP workers can increase aggregate pressure; multiplying a limit by worker count is only a rough risk check, not an accurate RAM forecast.<br />
<br />
PHP 8.5 also has a startup-level max_memory_limit setting that can cap memory_limit. If an intended change is capped or rejected, investigate the effective configuration and warning rather than repeatedly increasing the requested number.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify success and keep rollback information</span><br />
Repeat the same safe action with representative data. Confirm the application result is correct, the request finishes and no new matching fatal appears. Compare peak allocation, response time and server memory under an appropriate workload. A 200 response alone does not prove an import completed correctly.<br />
<br />
If a configuration change was used, verify the effective value in the website's PHP context. Restore the recorded value if it causes pressure or does not solve the problem. Remove diagnostic code and keep errors logged privately.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">When requesting support</span><br />
Share the PHP version, active limit, action, approximate input size, recent changes and a short redacted fatal-error excerpt. Do not post credentials, customer data or full configuration dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-change-php-upload-and-memory-limits-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Change PHP upload and memory settings</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Trace PHP HTTP 500 errors in logs</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">Size PHP-FPM workers using measurements</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://www.php.net/manual/en/ini.core.php#ini.memory-limit" target="_blank" rel="noopener" class="mycode_url">PHP memory-limit directives</a><br />
<a href="https://www.php.net/manual/en/function.memory-get-usage.php" target="_blank" rel="noopener" class="mycode_url">PHP allocation measurements and their limits</a><br />
<a href="https://www.php.net/manual/en/function.memory-get-peak-usage.php" target="_blank" rel="noopener" class="mycode_url">PHP peak-allocation function</a><br />
<a href="https://www.php.net/manual/en/function.ini-get.php" target="_blank" rel="noopener" class="mycode_url">Read the effective PHP configuration value</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">“Allowed memory size exhausted” means a PHP allocation hit the applicable memory limit. Confirm the fatal error and the website's active PHP settings before raising a limit: the real cause may be a large batch, a plugin, an image operation or inefficient code.</span><br />
<br />
This guide focuses on diagnosis and verification. The separate upload-and-memory-settings guide explains basic setting changes; an upload-size limit is not the same as the amount of memory an application needs while processing a request.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=325" target="_blank" title="">php-memory-20261015.jpg</a> (Size: 129.22 KB / Downloads: 3)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum private lab evidence, formatted as a transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Find the matching fatal error</span><br />
Record the failing action, URL path and time with timezone. Was it an import, export, image conversion, admin page or ordinary visit? Repeat only a safe action; an operation can have side effects before it fails.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the site and select <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Match the entry with the access log. On our lab the website error file is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log</code></div></div>Use your own configured domain and path. If PHP sends errors elsewhere, inspect the active PHP error-log destination and application logs too. Keep display_errors off on a public site; diagnose from private logs rather than exposing paths and stack traces to visitors.<br />
<br />
Our isolated PHP-FPM request produced:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP Fatal error: Allowed memory size of 16777216 bytes exhausted
(tried to allocate 33554464 bytes)</code></div></div>The allowed amount was 16 MiB. The attempted allocation is the size of a particular allocation attempt, not the application's total memory requirement. Do not add the two numbers and assume that is a reliable production setting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the PHP version and settings used by the website</span><br />
Confirm the site's selected PHP version in aaPanel first. The PHP executable used in SSH or a scheduled job can load different settings from PHP-FPM. Editing a CLI configuration does not prove the website changed.<br />
<br />
In a private diagnostic context within the relevant application request, useful values include:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP_VERSION
PHP_SAPI
php_ini_loaded_file()
ini_get('memory_limit')
memory_get_peak_usage(true)</code></div></div>These are diagnostic expressions, not a complete public endpoint to upload. Prefer temporary protected diagnostics or private application logging, and remove them when finished. A full phpinfo page reveals much more information than this investigation needs.<br />
<br />
Check for application overrides, per-directory configuration and PHP-FPM pool settings. If a pool administrator has locked a setting, an application-level change may not take effect. Verify the final value in the failing execution context rather than assuming a saved panel value wins.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. What our private PHP-FPM test showed</span><br />
We used a harmless PHP fixture outside the public website root and a separate loopback-only Nginx endpoint. The script applied and checked a <span style="font-weight: bold;" class="mycode_b">request-local 16M memory limit</span>; no shared php.ini or PHP-FPM pool setting was changed.<br />
<ul class="mycode_list"><li>A bulk attempt to create a 32 MiB string returned <span style="font-weight: bold;" class="mycode_b">HTTP 500</span>. The private Nginx error log captured the PHP memory fatal error.<br />
</li>
<li>A second request created and discarded thirty-two 1 MiB strings, one at a time. It counted <span style="font-weight: bold;" class="mycode_b">33,554,432 synthetic bytes</span> and returned <span style="font-weight: bold;" class="mycode_b">HTTP 200</span> under the same 16M limit.<br />
</li>
<li>The successful request identified its SAPI as <span style="font-weight: bold;" class="mycode_b">fpm-fcgi</span> and reported a peak PHP allocation of <span style="font-weight: bold;" class="mycode_b">2,097,152 bytes</span>. No new matching memory fatal appeared after it.<br />
</li>
</ul>
This was a synthetic allocation comparison. It did not read, validate or transform a real import, and it does not prove every application can be converted to chunked processing. It shows why total data handled and peak live allocation are different questions.<br />
<br />
The PHP fixture was removed, the private listener stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration, PHP-FPM pool configuration and php.ini were unchanged. The normal HTTPS site returned 200 afterward.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Investigate why this request needs so much memory</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Imports and exports:</span> check whether the application loads a whole file or result set into an array. Supported batching or streaming may reduce peak allocation; maintain correct validation, transaction handling and resumability.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Image processing:</span> compressed file size does not describe the memory needed for decoded pixels and transformations. Review image dimensions, format, library and concurrent jobs.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Plugins or recent changes:</span> compare the incident with deployment history and a controlled staging reproduction. Do not disable unrelated production features randomly.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Database results:</span> inspect how many rows and columns the application fetches and retains. A faster SQL query can still return an excessively large result.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Repeated growth:</span> check code that accumulates arrays, cached objects or repeated copies. The line reporting failure is where the next allocation failed, not necessarily where all earlier memory was consumed.<br />
</li>
</ul>
Collect evidence for one representative failing action before changing multiple settings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Distinguish PHP exhaustion from a server OOM event</span><br />
A PHP memory fatal is not proof that the entire VPS ran out of RAM. An operating-system or container memory kill is a different event and needs system-level evidence. Check the incident time against available memory, swap activity and system or service logs.<br />
<br />
PHP's own peak-allocation report is not the complete operating-system memory footprint of a worker. Extensions, shared allocations and other process overhead can make a worker's footprint larger. Do not size PHP-FPM concurrency using memory_limit alone.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. When a finite limit increase is justified</span><br />
Sometimes a legitimate operation needs more memory after application checks. Back up the relevant configuration, record the old value and scope, and review available headroom with the database and other services running.<br />
<br />
In aaPanel open the installed PHP version used by the site, then locate its configuration or limit settings. Panel labels vary. Determine whether the change affects every site on that PHP version or only the intended application. Apply the smallest measured finite change through the supported panel workflow and reload the relevant service if required.<br />
<br />
Avoid memory_limit=-1 as a blanket repair. Increasing per-request allowances alongside many PHP workers can increase aggregate pressure; multiplying a limit by worker count is only a rough risk check, not an accurate RAM forecast.<br />
<br />
PHP 8.5 also has a startup-level max_memory_limit setting that can cap memory_limit. If an intended change is capped or rejected, investigate the effective configuration and warning rather than repeatedly increasing the requested number.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify success and keep rollback information</span><br />
Repeat the same safe action with representative data. Confirm the application result is correct, the request finishes and no new matching fatal appears. Compare peak allocation, response time and server memory under an appropriate workload. A 200 response alone does not prove an import completed correctly.<br />
<br />
If a configuration change was used, verify the effective value in the website's PHP context. Restore the recorded value if it causes pressure or does not solve the problem. Remove diagnostic code and keep errors logged privately.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">When requesting support</span><br />
Share the PHP version, active limit, action, approximate input size, recent changes and a short redacted fatal-error excerpt. Do not post credentials, customer data or full configuration dumps.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-change-php-upload-and-memory-limits-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Change PHP upload and memory settings</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Trace PHP HTTP 500 errors in logs</a><br />
<a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">Size PHP-FPM workers using measurements</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://www.php.net/manual/en/ini.core.php#ini.memory-limit" target="_blank" rel="noopener" class="mycode_url">PHP memory-limit directives</a><br />
<a href="https://www.php.net/manual/en/function.memory-get-usage.php" target="_blank" rel="noopener" class="mycode_url">PHP allocation measurements and their limits</a><br />
<a href="https://www.php.net/manual/en/function.memory-get-peak-usage.php" target="_blank" rel="noopener" class="mycode_url">PHP peak-allocation function</a><br />
<a href="https://www.php.net/manual/en/function.ini-get.php" target="_blank" rel="noopener" class="mycode_url">Read the effective PHP configuration value</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix Primary Script Unknown PHP Errors in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-primary-script-unknown-php-errors-in-aapanel</link>
			<pubDate>Thu, 15 Oct 2026 13:05:11 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-primary-script-unknown-php-errors-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">If a PHP page returns “File not found” and the Nginx error log says “Primary script unknown,” investigate the script path sent to PHP-FPM. Restarting PHP or raising memory limits does not correct a wrong filename.</span><br />
<br />
This guide follows the request from the website's document root to PHP-FPM. We reproduced a deliberate filename mismatch on a private aaPanel lab endpoint and verified recovery by correcting only that path. Other causes still need evidence from your own logs.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=324" target="_blank" title="">php-path-20261015.jpg</a> (Size: 124.1 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, presented as a formatted transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Separate this error from other 404 responses</span><br />
A missing static image, an application route that does not exist and a PHP script-path error can all produce 404. The status alone cannot distinguish them. Record the exact request path, time and timezone, then check the matching error entry.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and use <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Check the access log for the same request. Labels may differ by panel version. Our lab site's files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log
/www/wwwlogs/adminslab.com.log</code></div></div>A short SSH check, using your actual configured domain and log path, is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Do not publish complete logs or configuration dumps; redact private query strings, credentials and customer details.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify which PHP handler received the request</span><br />
Our failing error entry included:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr: "Primary script unknown"
while reading response header from upstream</code></div></div>Its upstream field identified the local PHP 8.5-FPM socket used in our test. Your website may use another PHP version or socket. Confirm the site's selected PHP version and its active configuration instead of copying a socket path from a tutorial.<br />
<br />
This message shows that the FastCGI handler responded with a script problem. A connection-refused or missing-socket error points to a different investigation. Do not assume a working command-line PHP binary proves the website uses that same PHP version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Compare the public document root with the deployed files</span><br />
Open the site's directory settings and inspect the configured website root and, where applicable, its running directory. Then locate the application's intended public entry point in File Manager.<br />
<br />
For an illustrative deployment:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Application directory: /www/wwwroot/example.com/app
Public web directory:  /www/wwwroot/example.com/app/public
Public entry point:    /www/wwwroot/example.com/app/public/index.php</code></div></div>These are examples, not paths tested on your website. Follow the application's deployment requirements. Do not point the website at a private application directory merely to make an entry file reachable; that can expose configuration or other non-public files.<br />
<br />
Check for a moved deployment, wrong folder name, filename case mismatch, missing release or a broken symlink. Linux filenames are case-sensitive. A file you can see in one directory does not prove PHP-FPM is being told to execute that same file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Trace the filename passed to PHP-FPM</span><br />
In a conventional Nginx root-based PHP setup, a configuration may construct the path like this:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>fastcgi_param SCRIPT_FILENAME &#36;document_root&#36;fastcgi_script_name;</code></div></div>For example, a root of /www/wwwroot/example.com/public and a script name of /index.php would form /www/wwwroot/example.com/public/index.php. Inspect the active root, matching location and included PHP configuration together. Alias-based mappings, rewrites and path-info configurations require additional care; the simple example is not a universal replacement.<br />
<br />
Do not paste an extra SCRIPT_FILENAME directive on top of the panel's existing PHP include. Find the authoritative setting first. Changing a shared include can affect other websites, so back it up and understand its scope before editing anything.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated test proved</span><br />
The experiment used Nginx 1.30.5 and the installed PHP 8.5-FPM service. A separate Nginx instance listened only on loopback and accepted one exact test path. It did not alter the real website's routing.<br />
<ul class="mycode_list"><li>First, the private configuration sent a deliberately nonexistent script filename to PHP-FPM. The response was <span style="font-weight: bold;" class="mycode_b">404</span> with <span style="font-weight: bold;" class="mycode_b">File not found</span>, and the error log recorded <span style="font-weight: bold;" class="mycode_b">Primary script unknown</span>.<br />
</li>
<li>Next, we changed only that test filename to an existing, harmless PHP fixture. The response became <span style="font-weight: bold;" class="mycode_b">200</span> and contained the expected AdminsForum test message.<br />
</li>
<li>The error-log section after correction contained no new matching Primary script unknown error.<br />
</li>
</ul>
The disposable PHP file was outside the public website root. It was removed after the test, the private listener was stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration and PHP-FPM pool configuration were unchanged. The normal HTTPS website returned 200 afterward.<br />
<br />
This was a filename-mapping experiment, not a full application repair. It does not prove that your deployment has identical permissions, routing or filesystem restrictions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. If the path looks correct, check access and restrictions</span><ul class="mycode_list"><li>Confirm the target file actually exists at the computed absolute path and that each parent directory can be traversed by the relevant service account.<br />
</li>
<li>Check file ownership and read permissions against your deployment's intended accounts. Do not recursively apply 777 permissions or change the ownership of the whole server.<br />
</li>
<li>If a pool uses a filesystem jail or other path restrictions, compare the path visible inside that environment. A host-side path may not mean the same thing there.<br />
</li>
<li>Look for a specific open_basedir or permission-denied message. Keep the protection enabled while correcting an unintended path or narrowly reviewing the required access.<br />
</li>
<li>For framework routes, verify the expected entry point and application rewrite rules separately. A good index.php path does not automatically fix every missing application route.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply the smallest justified correction</span><br />
Back up the affected website configuration and record the current directory settings. Correct the demonstrated mismatch in the intended site scope. If an application deployment is incomplete, restore the missing release or entry point from the correct source rather than inventing a new index.php.<br />
<br />
Validate the complete Nginx configuration before applying a configuration change. If validation fails, restore the backup and investigate the reported line. Do not disable path checks or security controls as a generic repair.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify both execution and exposure</span><br />
Request one safe PHP page and confirm its expected content, not just status 200. Check that the error log has no new matching entry. Test an ordinary application route and a static asset, then confirm private application files remain inaccessible through the website.<br />
<br />
Remove any temporary diagnostic file you created. Avoid leaving phpinfo pages online. Keep the original configuration backup and record which path changed so you can roll back if another route breaks.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Locate website logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Investigate PHP HTTP 500 errors</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param" target="_blank" rel="noopener" class="mycode_url">Nginx FastCGI parameter documentation</a><br />
<a href="https://nginx.org/en/docs/http/request_processing.html" target="_blank" rel="noopener" class="mycode_url">How Nginx processes requests</a>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">If a PHP page returns “File not found” and the Nginx error log says “Primary script unknown,” investigate the script path sent to PHP-FPM. Restarting PHP or raising memory limits does not correct a wrong filename.</span><br />
<br />
This guide follows the request from the website's document root to PHP-FPM. We reproduced a deliberate filename mismatch on a private aaPanel lab endpoint and verified recovery by correcting only that path. Other causes still need evidence from your own logs.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=324" target="_blank" title="">php-path-20261015.jpg</a> (Size: 124.1 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Original AdminsForum lab evidence, presented as a formatted transcript rather than a screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Separate this error from other 404 responses</span><br />
A missing static image, an application route that does not exist and a PHP script-path error can all produce 404. The status alone cannot distinguish them. Record the exact request path, time and timezone, then check the matching error entry.<br />
<br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → PHP Project</span>, locate the affected site and use <span style="font-weight: bold;" class="mycode_b">Log → Error log</span>. Check the access log for the same request. Labels may differ by panel version. Our lab site's files are:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/wwwlogs/adminslab.com.error.log
/www/wwwlogs/adminslab.com.log</code></div></div>A short SSH check, using your actual configured domain and log path, is:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>tail -n 100 /www/wwwlogs/example.com.error.log</code></div></div>Do not publish complete logs or configuration dumps; redact private query strings, credentials and customer details.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Identify which PHP handler received the request</span><br />
Our failing error entry included:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr: "Primary script unknown"
while reading response header from upstream</code></div></div>Its upstream field identified the local PHP 8.5-FPM socket used in our test. Your website may use another PHP version or socket. Confirm the site's selected PHP version and its active configuration instead of copying a socket path from a tutorial.<br />
<br />
This message shows that the FastCGI handler responded with a script problem. A connection-refused or missing-socket error points to a different investigation. Do not assume a working command-line PHP binary proves the website uses that same PHP version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Compare the public document root with the deployed files</span><br />
Open the site's directory settings and inspect the configured website root and, where applicable, its running directory. Then locate the application's intended public entry point in File Manager.<br />
<br />
For an illustrative deployment:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>Application directory: /www/wwwroot/example.com/app
Public web directory:  /www/wwwroot/example.com/app/public
Public entry point:    /www/wwwroot/example.com/app/public/index.php</code></div></div>These are examples, not paths tested on your website. Follow the application's deployment requirements. Do not point the website at a private application directory merely to make an entry file reachable; that can expose configuration or other non-public files.<br />
<br />
Check for a moved deployment, wrong folder name, filename case mismatch, missing release or a broken symlink. Linux filenames are case-sensitive. A file you can see in one directory does not prove PHP-FPM is being told to execute that same file.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Trace the filename passed to PHP-FPM</span><br />
In a conventional Nginx root-based PHP setup, a configuration may construct the path like this:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>fastcgi_param SCRIPT_FILENAME &#36;document_root&#36;fastcgi_script_name;</code></div></div>For example, a root of /www/wwwroot/example.com/public and a script name of /index.php would form /www/wwwroot/example.com/public/index.php. Inspect the active root, matching location and included PHP configuration together. Alias-based mappings, rewrites and path-info configurations require additional care; the simple example is not a universal replacement.<br />
<br />
Do not paste an extra SCRIPT_FILENAME directive on top of the panel's existing PHP include. Find the authoritative setting first. Changing a shared include can affect other websites, so back it up and understand its scope before editing anything.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. What our isolated test proved</span><br />
The experiment used Nginx 1.30.5 and the installed PHP 8.5-FPM service. A separate Nginx instance listened only on loopback and accepted one exact test path. It did not alter the real website's routing.<br />
<ul class="mycode_list"><li>First, the private configuration sent a deliberately nonexistent script filename to PHP-FPM. The response was <span style="font-weight: bold;" class="mycode_b">404</span> with <span style="font-weight: bold;" class="mycode_b">File not found</span>, and the error log recorded <span style="font-weight: bold;" class="mycode_b">Primary script unknown</span>.<br />
</li>
<li>Next, we changed only that test filename to an existing, harmless PHP fixture. The response became <span style="font-weight: bold;" class="mycode_b">200</span> and contained the expected AdminsForum test message.<br />
</li>
<li>The error-log section after correction contained no new matching Primary script unknown error.<br />
</li>
</ul>
The disposable PHP file was outside the public website root. It was removed after the test, the private listener was stopped and its PID file disappeared. Hash checks confirmed the main Nginx configuration and PHP-FPM pool configuration were unchanged. The normal HTTPS website returned 200 afterward.<br />
<br />
This was a filename-mapping experiment, not a full application repair. It does not prove that your deployment has identical permissions, routing or filesystem restrictions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. If the path looks correct, check access and restrictions</span><ul class="mycode_list"><li>Confirm the target file actually exists at the computed absolute path and that each parent directory can be traversed by the relevant service account.<br />
</li>
<li>Check file ownership and read permissions against your deployment's intended accounts. Do not recursively apply 777 permissions or change the ownership of the whole server.<br />
</li>
<li>If a pool uses a filesystem jail or other path restrictions, compare the path visible inside that environment. A host-side path may not mean the same thing there.<br />
</li>
<li>Look for a specific open_basedir or permission-denied message. Keep the protection enabled while correcting an unintended path or narrowly reviewing the required access.<br />
</li>
<li>For framework routes, verify the expected entry point and application rewrite rules separately. A good index.php path does not automatically fix every missing application route.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">7. Apply the smallest justified correction</span><br />
Back up the affected website configuration and record the current directory settings. Correct the demonstrated mismatch in the intended site scope. If an application deployment is incomplete, restore the missing release or entry point from the correct source rather than inventing a new index.php.<br />
<br />
Validate the complete Nginx configuration before applying a configuration change. If validation fails, restore the backup and investigate the reported line. Do not disable path checks or security controls as a generic repair.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Verify both execution and exposure</span><br />
Request one safe PHP page and confirm its expected content, not just status 200. Check that the error log has no new matching entry. Test an ordinary application route and a static asset, then confirm private application files remain inaccessible through the website.<br />
<br />
Remove any temporary diagnostic file you created. Avoid leaving phpinfo pages online. Keep the original configuration backup and record which path changed so you can roll back if another route breaks.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Related guides</span><br />
<a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Locate website logs in aaPanel</a><br />
<a href="https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs" target="_blank" rel="noopener" class="mycode_url">Investigate PHP HTTP 500 errors</a><br />
<a href="https://adminsforum.com/Thread-guide-set-file-permissions-and-ownership-in-aapanel" target="_blank" rel="noopener" class="mycode_url">Review file permissions and ownership</a><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Technical references</span><br />
<a href="https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param" target="_blank" rel="noopener" class="mycode_url">Nginx FastCGI parameter documentation</a><br />
<a href="https://nginx.org/en/docs/http/request_processing.html" target="_blank" rel="noopener" class="mycode_url">How Nginx processes requests</a>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Fix PHP HTTP 500 Errors in aaPanel Using Error Logs]]></title>
			<link>https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs</link>
			<pubDate>Wed, 14 Oct 2026 21:11:00 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-fix-php-http-500-errors-in-aapanel-using-error-logs</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">HTTP 500 means the server could not complete the request. It does not tell you which PHP error occurred. Match the request with the relevant logs, identify the actual cause, make one targeted repair and verify the response and fresh log entries.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5, Nginx 1.30.5 and PHP 8.5.11. An isolated temporary PHP page called an undefined function, returned 500 and generated a fatal-error record. Removing that call returned 200 with the intended response and no new matching error entry. We removed the test page afterwards. No production application or global PHP settings were changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failing request</span><br />
Write down the exact hostname/path, time and timezone, method, status and recent changes. Check whether static files work, every PHP page fails or only one application action fails. Do not repeatedly submit an order, email or other side-effecting request merely to collect errors.<br />
For a harmless GET endpoint you control:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 15 -D - -o /dev/null https://example.com/problem-page</code></div></div>Replace the hostname and path. On Windows use curl.exe and NUL. Keep certificate validation enabled, and separately inspect the body. A browser's generic error page is not a diagnostic explanation.<br />
A CDN or application framework can return its own 500. Determine which layer handled the request before assuming the PHP service has stopped.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the matching website logs</span><br />
In the tested aaPanel interface choose Website → PHP Project → the exact site's Log button. Inspect Access log and Error log and use Refresh. Confirm the displayed source path and selected hostname.<br />
Our site used /www/wwwlogs/adminslab.com.log and /www/wwwlogs/adminslab.com.error.log. The application may use another private log too. The panel's administrative log is not a substitute for the website's log.<br />
Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Check Website Logs in aaPanel</a> for time matching, rotation and safe SSH searches.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Find the fatal error, not just the status code</span><br />
The lab access log recorded the temporary page with HTTP 500 at 13:08:03 UTC. The matching Nginx error entry contained:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr:
PHP Fatal error: Uncaught Error:
Call to undefined function af_lab_missing_function()
.../af-http500-verified-20261014.php:4</code></div></div>This identified an undefined function in the temporary script. It did not indicate that Nginx, MySQL or the entire VPS needed reinstalling. The file/line and error type directed the investigation.<br />
A framework stack can include several files. Trace the relevant application operation and recent deployment instead of editing a random vendor file named in the stack. Preserve a small matching excerpt before changing anything.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=310" target="_blank" title="">php-http500-20261014.jpg</a> (Size: 133.63 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab test, not a terminal screenshot. The image abbreviates the lab script path.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand what a syntax check proves</span><br />
Our faulty script passed:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -l /path/to/the/affected-file.php</code></div></div>Replace the path with an actual file and use the intended installed PHP binary. This command checks PHP syntax without executing the normal application workflow. It did not detect that our function was unavailable when the request ran.<br />
A successful lint does not establish runtime compatibility, autoloading, database access or correct application behavior. The CLI and PHP-FPM can also load different ini files and extensions. Verify the website's selected PHP version and its effective serving environment; do not change versions blindly to hide an error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Repair the cause shown by the error</span><br />
In our isolated demonstration, the repair was to remove the deliberately undefined call and return a fixed test message. We then repeated the same request. No service restart or pool increase was needed for this code error.<br />
For a real application, first back up and use staging or a reversible deployment. Example investigations include:<ul class="mycode_list"><li>Undefined function: check the function name, expected application include/autoloader or required extension. Determine which component supplies it before installing anything.<br />
</li>
<li>Class not found: inspect the deployment's dependencies and autoload configuration, including case-sensitive paths. Do not run arbitrary downloaded repair scripts.<br />
</li>
<li>Parse error: inspect the named file and recent edit, validate with the matching PHP version and deploy a corrected or known-good copy.<br />
</li>
<li>Memory exhausted: identify the request and resource cause. Raising memory limits without measurement may increase pressure across concurrent workers.<br />
</li>
<li>Database exception: inspect the application connection and matching database error; keep credentials out of public logs or support posts.<br />
</li>
</ul>
These are investigation examples, not additional failures triggered in this test. A 500 can have causes outside PHP as well; use the evidence actually recorded.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Keep diagnostics private and respect log-path restrictions</span><br />
Use error logging rather than public stack traces. For the controlled request we kept display_errors off and log_errors enabled. Global settings may need to be set before execution to capture startup or parse failures; a line inside a script may not execute when parsing fails.<br />
Our earlier attempt to choose a private custom log outside the website's allowed paths was blocked by open_basedir. The error appeared through FastCGI in the Nginx error log instead. We left the restriction intact and used the existing destination for the clean verification.<br />
If a configured log is empty, check effective PHP settings, its permitted path and write permissions. Do not disable open_basedir globally or apply chmod 777 as a logging fix. Choose a supported private destination that the application's restrictions permit, or use the existing SAPI/application logger.<br />
The FPM master log describes service diagnostics; it need not contain every application's fatal error. Avoid exposing phpinfo, debug logs or tokens on the website to discover a setting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify HTTP status, content and fresh logs</span><br />
At 13:08:06 UTC, the same temporary endpoint returned HTTP 200 and the text "AdminsForum clean recovery verified". Its access entry changed to 200, and there were no new error-log lines matching that page after the fix. The normal homepage also returned 200.<br />
We allowed timestamp revalidation time before checking the changed file. If your deployment disables OPcache timestamp checking, use its approved invalidation/reload process; a browser refresh alone does not guarantee fresh PHP bytecode.<br />
An old fatal entry remains historical evidence. Compare new timestamps and requests rather than clearing the log. Test an ordinary page and relevant application behavior, including reads/writes on staging where appropriate. A 200 with an error message in its body is not a complete recovery.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Clean up and retain a rollback</span><br />
We removed both temporary diagnostic pages created during the experiment and retained private test records. Existing website content, PHP pool settings and security restrictions were unchanged.<br />
Remove your own test files and temporary diagnostics after the observation window. Keep a known-good code/configuration backup and deliberate log retention. If a targeted change fails, restore it and verify service/application health again.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Distinguish a PHP 500 from a gateway failure</span><br />
A 502 or upstream connection refusal may mean Nginx cannot get a usable upstream response. An executing PHP script's fatal error is a different finding. Correlate upstream service and website logs before choosing a fix.<br />
For slow executing requests, use <a href="https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs" target="_blank" rel="noopener" class="mycode_url">PHP-FPM slow logs</a>; for shared-server pressure, use <a href="https://adminsforum.com/Thread-guide-monitor-server-resources-during-aapanel-website-traffic-tests" target="_blank" rel="noopener" class="mycode_url">resource monitoring during a controlled test</a>. Restarting everything can interrupt healthy services and hide useful evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/errorfunc.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP error logging configuration</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">HTTP 500 means the server could not complete the request. It does not tell you which PHP error occurred. Match the request with the relevant logs, identify the actual cause, make one targeted repair and verify the response and fresh log entries.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5, Nginx 1.30.5 and PHP 8.5.11. An isolated temporary PHP page called an undefined function, returned 500 and generated a fatal-error record. Removing that call returned 200 with the intended response and no new matching error entry. We removed the test page afterwards. No production application or global PHP settings were changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Record the failing request</span><br />
Write down the exact hostname/path, time and timezone, method, status and recent changes. Check whether static files work, every PHP page fails or only one application action fails. Do not repeatedly submit an order, email or other side-effecting request merely to collect errors.<br />
For a harmless GET endpoint you control:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>curl -sS --max-time 15 -D - -o /dev/null https://example.com/problem-page</code></div></div>Replace the hostname and path. On Windows use curl.exe and NUL. Keep certificate validation enabled, and separately inspect the body. A browser's generic error page is not a diagnostic explanation.<br />
A CDN or application framework can return its own 500. Determine which layer handled the request before assuming the PHP service has stopped.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the matching website logs</span><br />
In the tested aaPanel interface choose Website → PHP Project → the exact site's Log button. Inspect Access log and Error log and use Refresh. Confirm the displayed source path and selected hostname.<br />
Our site used /www/wwwlogs/adminslab.com.log and /www/wwwlogs/adminslab.com.error.log. The application may use another private log too. The panel's administrative log is not a substitute for the website's log.<br />
Read <a href="https://adminsforum.com/Thread-guide-check-website-logs-in-aapanel-to-troubleshoot-site-errors" target="_blank" rel="noopener" class="mycode_url">Check Website Logs in aaPanel</a> for time matching, rotation and safe SSH searches.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Find the fatal error, not just the status code</span><br />
The lab access log recorded the temporary page with HTTP 500 at 13:08:03 UTC. The matching Nginx error entry contained:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>FastCGI sent in stderr:
PHP Fatal error: Uncaught Error:
Call to undefined function af_lab_missing_function()
.../af-http500-verified-20261014.php:4</code></div></div>This identified an undefined function in the temporary script. It did not indicate that Nginx, MySQL or the entire VPS needed reinstalling. The file/line and error type directed the investigation.<br />
A framework stack can include several files. Trace the relevant application operation and recent deployment instead of editing a random vendor file named in the stack. Preserve a small matching excerpt before changing anything.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=310" target="_blank" title="">php-http500-20261014.jpg</a> (Size: 133.63 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab test, not a terminal screenshot. The image abbreviates the lab script path.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Understand what a syntax check proves</span><br />
Our faulty script passed:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -l /path/to/the/affected-file.php</code></div></div>Replace the path with an actual file and use the intended installed PHP binary. This command checks PHP syntax without executing the normal application workflow. It did not detect that our function was unavailable when the request ran.<br />
A successful lint does not establish runtime compatibility, autoloading, database access or correct application behavior. The CLI and PHP-FPM can also load different ini files and extensions. Verify the website's selected PHP version and its effective serving environment; do not change versions blindly to hide an error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Repair the cause shown by the error</span><br />
In our isolated demonstration, the repair was to remove the deliberately undefined call and return a fixed test message. We then repeated the same request. No service restart or pool increase was needed for this code error.<br />
For a real application, first back up and use staging or a reversible deployment. Example investigations include:<ul class="mycode_list"><li>Undefined function: check the function name, expected application include/autoloader or required extension. Determine which component supplies it before installing anything.<br />
</li>
<li>Class not found: inspect the deployment's dependencies and autoload configuration, including case-sensitive paths. Do not run arbitrary downloaded repair scripts.<br />
</li>
<li>Parse error: inspect the named file and recent edit, validate with the matching PHP version and deploy a corrected or known-good copy.<br />
</li>
<li>Memory exhausted: identify the request and resource cause. Raising memory limits without measurement may increase pressure across concurrent workers.<br />
</li>
<li>Database exception: inspect the application connection and matching database error; keep credentials out of public logs or support posts.<br />
</li>
</ul>
These are investigation examples, not additional failures triggered in this test. A 500 can have causes outside PHP as well; use the evidence actually recorded.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Keep diagnostics private and respect log-path restrictions</span><br />
Use error logging rather than public stack traces. For the controlled request we kept display_errors off and log_errors enabled. Global settings may need to be set before execution to capture startup or parse failures; a line inside a script may not execute when parsing fails.<br />
Our earlier attempt to choose a private custom log outside the website's allowed paths was blocked by open_basedir. The error appeared through FastCGI in the Nginx error log instead. We left the restriction intact and used the existing destination for the clean verification.<br />
If a configured log is empty, check effective PHP settings, its permitted path and write permissions. Do not disable open_basedir globally or apply chmod 777 as a logging fix. Choose a supported private destination that the application's restrictions permit, or use the existing SAPI/application logger.<br />
The FPM master log describes service diagnostics; it need not contain every application's fatal error. Avoid exposing phpinfo, debug logs or tokens on the website to discover a setting.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Verify HTTP status, content and fresh logs</span><br />
At 13:08:06 UTC, the same temporary endpoint returned HTTP 200 and the text "AdminsForum clean recovery verified". Its access entry changed to 200, and there were no new error-log lines matching that page after the fix. The normal homepage also returned 200.<br />
We allowed timestamp revalidation time before checking the changed file. If your deployment disables OPcache timestamp checking, use its approved invalidation/reload process; a browser refresh alone does not guarantee fresh PHP bytecode.<br />
An old fatal entry remains historical evidence. Compare new timestamps and requests rather than clearing the log. Test an ordinary page and relevant application behavior, including reads/writes on staging where appropriate. A 200 with an error message in its body is not a complete recovery.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Clean up and retain a rollback</span><br />
We removed both temporary diagnostic pages created during the experiment and retained private test records. Existing website content, PHP pool settings and security restrictions were unchanged.<br />
Remove your own test files and temporary diagnostics after the observation window. Keep a known-good code/configuration backup and deliberate log retention. If a targeted change fails, restore it and verify service/application health again.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Distinguish a PHP 500 from a gateway failure</span><br />
A 502 or upstream connection refusal may mean Nginx cannot get a usable upstream response. An executing PHP script's fatal error is a different finding. Correlate upstream service and website logs before choosing a fix.<br />
For slow executing requests, use <a href="https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs" target="_blank" rel="noopener" class="mycode_url">PHP-FPM slow logs</a>; for shared-server pressure, use <a href="https://adminsforum.com/Thread-guide-monitor-server-resources-during-aapanel-website-traffic-tests" target="_blank" rel="noopener" class="mycode_url">resource monitoring during a controlled test</a>. Restarting everything can interrupt healthy services and hide useful evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/errorfunc.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP error logging configuration</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Find Slow PHP Requests in aaPanel with PHP-FPM Slow Logs]]></title>
			<link>https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs</link>
			<pubDate>Wed, 14 Oct 2026 20:35:09 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-find-slow-php-requests-in-aapanel-with-php-fpm-slow-logs</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">PHP-FPM's slow log can show where a PHP request was executing after it crossed a time threshold. Use that evidence to investigate application work before raising worker counts or timeouts.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5 and PHP 8.5.11. We ran one synthetic four-second request through the private PHP-FPM Unix socket. It generated a slow-log trace, after which we restored the original pool settings and removed the test script. No production website was changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the PHP version and pool</span><br />
Check the website's selected PHP version in aaPanel. Inspect its Nginx PHP handler if you administer the server. Our site used /tmp/php-cgi-85.sock and pool www. The default command-line PHP binary may load a different configuration and cannot prove which pool serves the site.<br />
The lab pool configuration was /www/server/php/85/etc/php-fpm.conf. Version numbers and paths vary: discover the actual file before editing. Read <a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">the PHP-FPM worker guide</a> for the distinction between worker limits and request cost.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check existing logging settings</span><br />
Our original configuration included:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>request_slowlog_timeout = 30
slowlog = var/log/slow.log
request_terminate_timeout = 100</code></div></div>A request below the slow-log threshold will not generate a slow trace simply because a visitor considers it slow. The relative log path must be interpreted in the running FPM installation; do not assume it is inside the website directory. We used an explicit absolute path for the experiment to avoid that ambiguity.<br />
The slow-log threshold requests a diagnostic backtrace. The termination timeout is a separate setting that can kill a long-running worker request; we left it unchanged. Raising either is not a cure for slow SQL or an unavailable API.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Back up and select a diagnostic threshold</span><br />
Keep an original copy of the pool configuration and a working SSH recovery route. On a shared PHP version, the change can affect several websites. Choose a threshold suited to the symptom and a limited observation window, rather than permanently logging every ordinary request.<br />
For our isolated lab example we temporarily used:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>request_slowlog_timeout = 2
slowlog = /www/server/php/85/var/log/af-slowlog-lab-20261014.log</code></div></div>Keep logs outside publicly served directories and restrict access. Paths and stack traces can reveal implementation details. Use your own private log path and ensure the FPM master can open it; avoid broad permission changes such as chmod 777.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Validate before reloading</span><br />
On this lab installation:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div>The configuration test passed. Reload only after success and inspect application health afterwards. Use the service names and binary for your selected version. A valid configuration does not guarantee the diagnostic backtrace will succeed on every container or host; inspect FPM errors if tracing is restricted.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Generate one controlled slow request</span><br />
Our test script contained only:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>&lt;?php
sleep(4);
echo "AdminsForum slow-log lab completed&#92;n";</code></div></div>It was stored outside the website root and executed through cgi-fcgi over /tmp/php-cgi-85.sock using a local administrator session. The request had a client timeout and completed in about 4.004 seconds. We did not publish a slow test URL, start a traffic loop or trigger real customer actions.<br />
If reproducing this lesson, use an isolated lab and its actual private socket. Do not upload a deliberate delay script to a public production website. For a real symptom, collect traces from a bounded legitimate test workflow instead.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=295" target="_blank" title="">php-slowlog-20261014.jpg</a> (Size: 111.23 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab result, not a terminal screenshot. The image abbreviates the private diagnostic path.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Read the trace</span><br />
The log named pool www and the test script, then identified sleep() on line 1. That is consistent with the intentional waiting operation. It confirms that slow logging worked for this request.<br />
A trace is a snapshot of execution, not a complete timeline or a ranked profiler. A function visible in one sample is not automatically the root cause. Compare several relevant traces and correlate the request time with application, database and web-server evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Follow the evidence to the right component</span><ul class="mycode_list"><li>A database call in the trace: identify the corresponding query and inspect its plan and database timing. Follow <a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">the EXPLAIN and index test guide</a>.<br />
</li>
<li>An HTTP/API operation: inspect destination latency, connection errors and application timeout handling. Do not repeatedly retry a side-effecting request just to gather samples.<br />
</li>
<li>Repeated application functions: use a suitable application profiler in a controlled environment and compare expensive paths. The slow log alone does not quantify every function's cost.<br />
</li>
<li>Many occupied workers: combine traces with CPU, memory and FPM queue observations. Queueing before a request starts running in a worker may not be explained by its eventual slow trace.<br />
</li>
</ul>
A full-page cache HIT may bypass PHP entirely. Use the cache verification guide to distinguish that path from a PHP request. Do not infer that logging is broken solely because cached pages produce no PHP trace.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Restore and verify</span><br />
Our test restored the original configuration byte for byte, validated it and reloaded the service. We removed the temporary script and retained the private trace and backup for documentation. The original 30-second threshold and existing log path were restored; the termination limit was unchanged.<br />
After your diagnostic window, restore the previous settings or choose a deliberate long-term policy with log retention and disk monitoring. Keep raw traces private and redact paths and user-related details before asking for public help.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Retest the actual fix</span><br />
Change one identified cause, repeat the same meaningful workflow and compare response time, errors and resource use. Keep a rollback plan. Disabling diagnostics, adding workers or increasing a timeout without evidence does not establish that the cause was fixed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/install.fpm.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP-FPM configuration documentation</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">PHP-FPM's slow log can show where a PHP request was executing after it crossed a time threshold. Use that evidence to investigate application work before raising worker counts or timeouts.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested</span>: aaPanel Free 8.0.7, Ubuntu 22.04.5 and PHP 8.5.11. We ran one synthetic four-second request through the private PHP-FPM Unix socket. It generated a slow-log trace, after which we restored the original pool settings and removed the test script. No production website was changed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the PHP version and pool</span><br />
Check the website's selected PHP version in aaPanel. Inspect its Nginx PHP handler if you administer the server. Our site used /tmp/php-cgi-85.sock and pool www. The default command-line PHP binary may load a different configuration and cannot prove which pool serves the site.<br />
The lab pool configuration was /www/server/php/85/etc/php-fpm.conf. Version numbers and paths vary: discover the actual file before editing. Read <a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">the PHP-FPM worker guide</a> for the distinction between worker limits and request cost.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check existing logging settings</span><br />
Our original configuration included:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>request_slowlog_timeout = 30
slowlog = var/log/slow.log
request_terminate_timeout = 100</code></div></div>A request below the slow-log threshold will not generate a slow trace simply because a visitor considers it slow. The relative log path must be interpreted in the running FPM installation; do not assume it is inside the website directory. We used an explicit absolute path for the experiment to avoid that ambiguity.<br />
The slow-log threshold requests a diagnostic backtrace. The termination timeout is a separate setting that can kill a long-running worker request; we left it unchanged. Raising either is not a cure for slow SQL or an unavailable API.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Back up and select a diagnostic threshold</span><br />
Keep an original copy of the pool configuration and a working SSH recovery route. On a shared PHP version, the change can affect several websites. Choose a threshold suited to the symptom and a limited observation window, rather than permanently logging every ordinary request.<br />
For our isolated lab example we temporarily used:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>request_slowlog_timeout = 2
slowlog = /www/server/php/85/var/log/af-slowlog-lab-20261014.log</code></div></div>Keep logs outside publicly served directories and restrict access. Paths and stack traces can reveal implementation details. Use your own private log path and ensure the FPM master can open it; avoid broad permission changes such as chmod 777.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Validate before reloading</span><br />
On this lab installation:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div>The configuration test passed. Reload only after success and inspect application health afterwards. Use the service names and binary for your selected version. A valid configuration does not guarantee the diagnostic backtrace will succeed on every container or host; inspect FPM errors if tracing is restricted.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Generate one controlled slow request</span><br />
Our test script contained only:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>&lt;?php
sleep(4);
echo "AdminsForum slow-log lab completed&#92;n";</code></div></div>It was stored outside the website root and executed through cgi-fcgi over /tmp/php-cgi-85.sock using a local administrator session. The request had a client timeout and completed in about 4.004 seconds. We did not publish a slow test URL, start a traffic loop or trigger real customer actions.<br />
If reproducing this lesson, use an isolated lab and its actual private socket. Do not upload a deliberate delay script to a public production website. For a real symptom, collect traces from a bounded legitimate test workflow instead.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=295" target="_blank" title="">php-slowlog-20261014.jpg</a> (Size: 111.23 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original lab result, not a terminal screenshot. The image abbreviates the private diagnostic path.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Read the trace</span><br />
The log named pool www and the test script, then identified sleep() on line 1. That is consistent with the intentional waiting operation. It confirms that slow logging worked for this request.<br />
A trace is a snapshot of execution, not a complete timeline or a ranked profiler. A function visible in one sample is not automatically the root cause. Compare several relevant traces and correlate the request time with application, database and web-server evidence.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Follow the evidence to the right component</span><ul class="mycode_list"><li>A database call in the trace: identify the corresponding query and inspect its plan and database timing. Follow <a href="https://adminsforum.com/Thread-guide-tune-mariadb-queries-in-aapanel-with-explain-and-index-tests" target="_blank" rel="noopener" class="mycode_url">the EXPLAIN and index test guide</a>.<br />
</li>
<li>An HTTP/API operation: inspect destination latency, connection errors and application timeout handling. Do not repeatedly retry a side-effecting request just to gather samples.<br />
</li>
<li>Repeated application functions: use a suitable application profiler in a controlled environment and compare expensive paths. The slow log alone does not quantify every function's cost.<br />
</li>
<li>Many occupied workers: combine traces with CPU, memory and FPM queue observations. Queueing before a request starts running in a worker may not be explained by its eventual slow trace.<br />
</li>
</ul>
A full-page cache HIT may bypass PHP entirely. Use the cache verification guide to distinguish that path from a PHP request. Do not infer that logging is broken solely because cached pages produce no PHP trace.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Restore and verify</span><br />
Our test restored the original configuration byte for byte, validated it and reloaded the service. We removed the temporary script and retained the private trace and backup for documentation. The original 30-second threshold and existing log path were restored; the termination limit was unchanged.<br />
After your diagnostic window, restore the previous settings or choose a deliberate long-term policy with log retention and disk monitoring. Keep raw traces private and redact paths and user-related details before asking for public help.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">9. Retest the actual fix</span><br />
Change one identified cause, repeat the same meaningful workflow and compare response time, errors and resource use. Keep a rollback plan. Disabling diagnostics, adding workers or increasing a timeout without evidence does not establish that the cause was fixed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/install.fpm.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP-FPM configuration documentation</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Measure PHP OPcache Performance in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-measure-php-opcache-performance-in-aapanel</link>
			<pubDate>Wed, 14 Oct 2026 20:14:21 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-measure-php-opcache-performance-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">OPcache stores compiled PHP bytecode so PHP-FPM can reuse it instead of compiling the same scripts for every request. This guide measures that effect on a small WordPress lab and explains how to verify the serving runtime.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Test environment</span><br />
aaPanel Free 8.0.7, Ubuntu 22.04.5, PHP 8.5.11, Nginx and WordPress. OPcache was already enabled before the experiment. We temporarily disabled it for the comparison and left it enabled afterwards. No production website was used.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the PHP version serving the website</span><br />
Open Website → your site and inspect its PHP version. Our site used PHP 8.5 through /tmp/php-cgi-85.sock. A command-line PHP result alone cannot prove what PHP-FPM is doing: CLI and FPM may load different configuration files.<br />
Read <a href="https://adminsforum.com/Thread-guide-check-php-opcache-in-aapanel-cli-vs-php-fpm" target="_blank" rel="noopener" class="mycode_url">Check PHP OPcache: CLI vs PHP-FPM</a> first if those results disagree.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Back up the active configuration</span><br />
In App Store → Installed → PHP-8.5 → Setting, inspect the configuration and available extensions. Interface labels depend on the panel release. Confirm the active FPM php.ini before editing; our FPM runtime loaded /www/server/php/85/etc/php.ini, while CLI loaded php-cli.ini.<br />
Keep a backup and working SSH access. A setting change affects the websites sharing that PHP version. Schedule a suitable maintenance window for a busy server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Use a measured starting configuration</span><br />
Our retained lab settings were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2</code></div></div>The memory value is MiB. The file setting controls the script-cache table size; the actual key capacity may differ from the number configured. Check the runtime rather than assuming they are identical.<br />
Timestamp validation allows changed files to be detected; the revalidation interval controls how frequently checks occur. Disabling validation requires a reliable deployment invalidation process. We kept it enabled and did not change JIT settings.<br />
Do not increase these values merely because traffic increased. Look for cache exhaustion, restarts and the application’s script count, while reserving RAM for other services.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Validate and reload the correct pool</span><br />
Our SSH checks were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div>Validation passed before each reload. Syntax success does not prove the application works: check important pages and error logs afterwards. Restore the backup and reload if the change causes failures.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Verify OPcache through PHP-FPM privately</span><br />
Our diagnostic script used opcache_get_status(false) and php_ini_loaded_file() through the private Unix socket. It was outside the website root. Passing false excludes the detailed cached-script path listing.<br />
The enabled phase reported FPM SAPI fpm-fcgi, PHP 8.5.11, 532 cached scripts, about 29MiB used and 99MiB free, with zero out-of-memory and hash restarts at that observation. These values describe this small workload, not the needs of every WordPress installation.<br />
Do not publish phpinfo or cache status on an unprotected URL: configuration and paths can disclose server details. Remove temporary diagnostics when finished.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Separate page caching from bytecode caching</span><br />
A full-page cache HIT may avoid PHP entirely. We used unique query strings and verified Nginx-Cache: BYPASS under our existing rules. Query strings do not universally bypass caches; check your own configuration and response headers.<br />
Each phase used 20 warmup requests followed by 20 measured requests at concurrency 2. Requests used loopback HTTPS with normal certificate validation. This isolates much of the network variation but does not represent a remote visitor’s full browser experience.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=290" target="_blank" title="">opcache-comparison-20261014.jpg</a> (Size: 117.41 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original experiment, not a terminal screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Interpret the results</span><ul class="mycode_list"><li>OPcache off: 20/20 HTTP 200; median time to first byte 490ms; small-sample p95 555ms.<br />
</li>
<li>OPcache on: 20/20 HTTP 200; median time to first byte 168ms; small-sample p95 190ms.<br />
</li>
</ul>
This workload was faster with OPcache enabled. Twenty requests give limited tail-latency evidence and do not establish maximum visitor capacity. Repeat tests on expensive pages and representative workloads before making production promises.<br />
Runtime hit/miss counters can include warmup and other requests since the cache started; do not treat a cumulative hit ratio as the measured phase alone.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Monitor and revisit sizing</span><br />
Inspect memory used/free/wasted, cached-script count, misses and restart counters over a representative period. An exhausted cache may need additional memory or key capacity; frequent deployments and invalidation also affect results. Check PHP errors and memory pressure alongside cache statistics.<br />
OPcache does not replace SQL indexes, object caching or page caching. Use <a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">measured PHP-FPM worker limits</a> to control concurrent process memory separately.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/opcache.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP OPcache configuration documentation</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">OPcache stores compiled PHP bytecode so PHP-FPM can reuse it instead of compiling the same scripts for every request. This guide measures that effect on a small WordPress lab and explains how to verify the serving runtime.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Test environment</span><br />
aaPanel Free 8.0.7, Ubuntu 22.04.5, PHP 8.5.11, Nginx and WordPress. OPcache was already enabled before the experiment. We temporarily disabled it for the comparison and left it enabled afterwards. No production website was used.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the PHP version serving the website</span><br />
Open Website → your site and inspect its PHP version. Our site used PHP 8.5 through /tmp/php-cgi-85.sock. A command-line PHP result alone cannot prove what PHP-FPM is doing: CLI and FPM may load different configuration files.<br />
Read <a href="https://adminsforum.com/Thread-guide-check-php-opcache-in-aapanel-cli-vs-php-fpm" target="_blank" rel="noopener" class="mycode_url">Check PHP OPcache: CLI vs PHP-FPM</a> first if those results disagree.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Back up the active configuration</span><br />
In App Store → Installed → PHP-8.5 → Setting, inspect the configuration and available extensions. Interface labels depend on the panel release. Confirm the active FPM php.ini before editing; our FPM runtime loaded /www/server/php/85/etc/php.ini, while CLI loaded php-cli.ini.<br />
Keep a backup and working SSH access. A setting change affects the websites sharing that PHP version. Schedule a suitable maintenance window for a busy server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Use a measured starting configuration</span><br />
Our retained lab settings were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2</code></div></div>The memory value is MiB. The file setting controls the script-cache table size; the actual key capacity may differ from the number configured. Check the runtime rather than assuming they are identical.<br />
Timestamp validation allows changed files to be detected; the revalidation interval controls how frequently checks occur. Disabling validation requires a reliable deployment invalidation process. We kept it enabled and did not change JIT settings.<br />
Do not increase these values merely because traffic increased. Look for cache exhaustion, restarts and the application’s script count, while reserving RAM for other services.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Validate and reload the correct pool</span><br />
Our SSH checks were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div>Validation passed before each reload. Syntax success does not prove the application works: check important pages and error logs afterwards. Restore the backup and reload if the change causes failures.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Verify OPcache through PHP-FPM privately</span><br />
Our diagnostic script used opcache_get_status(false) and php_ini_loaded_file() through the private Unix socket. It was outside the website root. Passing false excludes the detailed cached-script path listing.<br />
The enabled phase reported FPM SAPI fpm-fcgi, PHP 8.5.11, 532 cached scripts, about 29MiB used and 99MiB free, with zero out-of-memory and hash restarts at that observation. These values describe this small workload, not the needs of every WordPress installation.<br />
Do not publish phpinfo or cache status on an unprotected URL: configuration and paths can disclose server details. Remove temporary diagnostics when finished.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Separate page caching from bytecode caching</span><br />
A full-page cache HIT may avoid PHP entirely. We used unique query strings and verified Nginx-Cache: BYPASS under our existing rules. Query strings do not universally bypass caches; check your own configuration and response headers.<br />
Each phase used 20 warmup requests followed by 20 measured requests at concurrency 2. Requests used loopback HTTPS with normal certificate validation. This isolates much of the network variation but does not represent a remote visitor’s full browser experience.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=290" target="_blank" title="">opcache-comparison-20261014.jpg</a> (Size: 117.41 KB / Downloads: 6)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">AdminsForum formatted transcript of the original experiment, not a terminal screenshot.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Interpret the results</span><ul class="mycode_list"><li>OPcache off: 20/20 HTTP 200; median time to first byte 490ms; small-sample p95 555ms.<br />
</li>
<li>OPcache on: 20/20 HTTP 200; median time to first byte 168ms; small-sample p95 190ms.<br />
</li>
</ul>
This workload was faster with OPcache enabled. Twenty requests give limited tail-latency evidence and do not establish maximum visitor capacity. Repeat tests on expensive pages and representative workloads before making production promises.<br />
Runtime hit/miss counters can include warmup and other requests since the cache started; do not treat a cumulative hit ratio as the measured phase alone.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Monitor and revisit sizing</span><br />
Inspect memory used/free/wasted, cached-script count, misses and restart counters over a representative period. An exhausted cache may need additional memory or key capacity; frequent deployments and invalidation also affect results. Check PHP errors and memory pressure alongside cache statistics.<br />
OPcache does not replace SQL indexes, object caching or page caching. Use <a href="https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits" target="_blank" rel="noopener" class="mycode_url">measured PHP-FPM worker limits</a> to control concurrent process memory separately.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference</span>: <a href="https://www.php.net/manual/en/opcache.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP OPcache configuration documentation</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Tune PHP-FPM Workers in aaPanel with Measured Memory Limits]]></title>
			<link>https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits</link>
			<pubDate>Wed, 14 Oct 2026 20:01:50 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-tune-php-fpm-workers-in-aapanel-with-measured-memory-limits</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">PHP-FPM worker limits should fit the memory and workload of the PHP applications on your server. Measure warmed workers, reserve resources for the database and other services, then compare a controlled workload before increasing concurrency.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested:</span> aaPanel Free 8.0.7, Ubuntu 22.04.5, two CPUs and 3.8Gi RAM. WordPress uses the PHP 8.5 FPM socket /tmp/php-cgi-85.sock. We backed up the pool configuration and tested a smaller dynamic pool. This is a lab sizing example, not a universal high-traffic configuration.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Establish a baseline and confirm the right PHP version</span><br />
Start with <a href="https://adminsforum.com/Thread-guide-measure-aapanel-website-performance-before-tuning-your-server" target="_blank" rel="noopener" class="mycode_url">Measure Website Performance Before Tuning</a>. In aaPanel, confirm the website's selected PHP version. The default command-line php can be a different version from the PHP-FPM pool serving the site.<br />
<br />
Our actual Nginx handler used PHP 8.5 through a Unix socket. We left its connection address and permissions unchanged. Review every site sharing the PHP version before changing a global pool: the settings can affect more than one website.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Warm the workload and separate cache hits from PHP work</span><br />
A cached anonymous response may never reach PHP. In our lab, the existing Nginx FastCGI rules bypass cache for requests with a query string. We verified the response header <span style="font-weight: bold;" class="mycode_b">Nginx-Cache: BYPASS</span> for the measured WordPress requests.<br />
<br />
We sent 20 warmup requests, then measured 20 requests at concurrency 2 in each phase. Requests used the same lab hostname over loopback HTTPS with normal certificate validation. This removes most external network variation but does not simulate remote users or a full browser.<br />
<br />
Do not assume adding a query string bypasses every cache. Inspect your own rules and headers. Test representative pages, including the expensive workflows your users actually perform.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Measure worker memory</span><br />
Useful SSH checks include:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ps -eo pid,ppid,user,rss,comm | grep php-fpm</code></div></div>Identify the master for the correct PHP version and measure its children. RSS includes shared pages; adding every RSS value can double-count shared memory. On Linux, /proc/PID/smaps_rollup includes proportional set size (PSS), which distributes shared pages between processes. Reading these files may require administrator privileges.<br />
<br />
After the cache-bypassed warmup, our sampled workers had a maximum RSS around 51–53MiB. Other pages, plugins and traffic can use more. These are sampled values, not guaranteed per-worker maximums. Reserve extra headroom rather than basing the entire pool on the smallest idle worker.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Choose a memory budget before choosing a worker count</span><br />
Reserve memory for the OS, Nginx, database, Redis, mail and any other PHP versions. Estimate a ceiling:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>worker ceiling ≈ PHP memory budget / conservative memory per worker</code></div></div>This is an upper-bound planning estimate, not a throughput recommendation. Shared memory, request spikes and application behavior still need measurement. CPU capacity, database limits and acceptable queue time can require a smaller count.<br />
<br />
For this shared 3.8Gi lab we used a conservative 1GiB PHP planning budget and a 100MiB per-worker allowance, larger than this light sample. That suggests roughly ten workers before additional headroom; we tested a limit of eight. Do not copy eight simply because your server also has 4GB RAM.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Open the native aaPanel worker settings</span><br />
Choose <span style="font-weight: bold;" class="mycode_b">App Store → Installed → PHP-8.5 → Setting → Optimization</span>. In our release, the form includes Running mode, max_children, start_servers, min_spare_servers and max_spare_servers.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=289" target="_blank" title="">php-fpm-optimization-20261014.jpg</a> (Size: 203.89 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The native PHP Optimization screen shows the tested dynamic-pool values.</span><br />
<br />
The lab changes were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>pm = dynamic
pm.max_children = 8
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4</code></div></div>Previously the pool used max_children 80, start_servers 10, min_spare_servers 10 and max_spare_servers 30. The form's RAM presets and approximate per-worker memory guidance cannot replace your application's measurements.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What each setting does</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">pm.max_children:</span> the pool's simultaneous request-worker limit. Requests can queue when all workers are busy.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">pm.start_servers:</span> initial children for dynamic mode.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">pm.min_spare_servers:</span> desired minimum idle children in dynamic mode.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">pm.max_spare_servers:</span> desired maximum idle children in dynamic mode.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">static mode:</span> keeps a fixed worker count; plan its persistent memory use.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">ondemand mode:</span> spawns workers when needed; startup behavior and idle settings differ from dynamic mode.<br />
</li>
</ul>
Raising workers cannot make slow SQL or external APIs fast, and can overload shared resources. Lowering workers can reduce idle memory but increase queueing under traffic.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Back up, validate and reload</span><br />
We backed up /www/server/php/85/etc/php-fpm.conf before editing it through SSH, then ran:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div>Configuration validation passed. The native screen was inspected afterwards and reflected the saved values. For a UI change, use its Save action and verify the resulting configuration and service state; our test applied the changes through SSH rather than claiming we clicked Save in the UI.<br />
<br />
A configuration test proves syntax, not application behavior. Keep the backup and a working SSH recovery route. Restore it and reload if meaningful requests fail or monitoring shows unacceptable queueing/resource use.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Compare the same workload honestly</span><br />
After 20 warmup requests, each measured phase used 20 requests at concurrency 2:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Before:</span> 20/20 HTTP 200; median TTFB 173 ms; sample p95 189 ms; 12 sampled children; aggregate child PSS about 113MiB.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">After:</span> 20/20 HTTP 200; median TTFB 180 ms; sample p95 196 ms; 4 sampled children; aggregate child PSS about 72MiB.<br />
</li>
</ul>
The smaller pool used less aggregate child memory in this snapshot. It did not make this workload faster. The small latency difference can include normal variability, and 20 requests provide limited tail-latency evidence. We did not establish maximum throughput or prove eight workers fits production peak traffic.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Monitor queues and real traffic before a production decision</span><br />
Inspect PHP-FPM status, listen-queue behavior, slow requests, memory pressure, CPU saturation and database activity under a representative bounded load. Keep status endpoints private. Increase a limit only when evidence shows workers are the bottleneck and the server has resources for them.<br />
<br />
Do not use PHP memory_limit multiplied by worker count as an exact process-memory measurement. Keep application errors and OOM events in view, and test expensive pages as well as the homepage.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://www.php.net/manual/en/install.fpm.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP-FPM configuration documentation</a>.<br />
<span style="font-style: italic;" class="mycode_i">AdminsForum performance series. Original pool configuration retained at /www/backup/af-performance-20261014/php85-fpm-before.conf in the lab; do not publish your own private configuration values.</span>]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">PHP-FPM worker limits should fit the memory and workload of the PHP applications on your server. Measure warmed workers, reserve resources for the database and other services, then compare a controlled workload before increasing concurrency.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested:</span> aaPanel Free 8.0.7, Ubuntu 22.04.5, two CPUs and 3.8Gi RAM. WordPress uses the PHP 8.5 FPM socket /tmp/php-cgi-85.sock. We backed up the pool configuration and tested a smaller dynamic pool. This is a lab sizing example, not a universal high-traffic configuration.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Establish a baseline and confirm the right PHP version</span><br />
Start with <a href="https://adminsforum.com/Thread-guide-measure-aapanel-website-performance-before-tuning-your-server" target="_blank" rel="noopener" class="mycode_url">Measure Website Performance Before Tuning</a>. In aaPanel, confirm the website's selected PHP version. The default command-line php can be a different version from the PHP-FPM pool serving the site.<br />
<br />
Our actual Nginx handler used PHP 8.5 through a Unix socket. We left its connection address and permissions unchanged. Review every site sharing the PHP version before changing a global pool: the settings can affect more than one website.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Warm the workload and separate cache hits from PHP work</span><br />
A cached anonymous response may never reach PHP. In our lab, the existing Nginx FastCGI rules bypass cache for requests with a query string. We verified the response header <span style="font-weight: bold;" class="mycode_b">Nginx-Cache: BYPASS</span> for the measured WordPress requests.<br />
<br />
We sent 20 warmup requests, then measured 20 requests at concurrency 2 in each phase. Requests used the same lab hostname over loopback HTTPS with normal certificate validation. This removes most external network variation but does not simulate remote users or a full browser.<br />
<br />
Do not assume adding a query string bypasses every cache. Inspect your own rules and headers. Test representative pages, including the expensive workflows your users actually perform.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Measure worker memory</span><br />
Useful SSH checks include:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>ps -eo pid,ppid,user,rss,comm | grep php-fpm</code></div></div>Identify the master for the correct PHP version and measure its children. RSS includes shared pages; adding every RSS value can double-count shared memory. On Linux, /proc/PID/smaps_rollup includes proportional set size (PSS), which distributes shared pages between processes. Reading these files may require administrator privileges.<br />
<br />
After the cache-bypassed warmup, our sampled workers had a maximum RSS around 51–53MiB. Other pages, plugins and traffic can use more. These are sampled values, not guaranteed per-worker maximums. Reserve extra headroom rather than basing the entire pool on the smallest idle worker.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Choose a memory budget before choosing a worker count</span><br />
Reserve memory for the OS, Nginx, database, Redis, mail and any other PHP versions. Estimate a ceiling:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>worker ceiling ≈ PHP memory budget / conservative memory per worker</code></div></div>This is an upper-bound planning estimate, not a throughput recommendation. Shared memory, request spikes and application behavior still need measurement. CPU capacity, database limits and acceptable queue time can require a smaller count.<br />
<br />
For this shared 3.8Gi lab we used a conservative 1GiB PHP planning budget and a 100MiB per-worker allowance, larger than this light sample. That suggests roughly ten workers before additional headroom; we tested a limit of eight. Do not copy eight simply because your server also has 4GB RAM.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Open the native aaPanel worker settings</span><br />
Choose <span style="font-weight: bold;" class="mycode_b">App Store → Installed → PHP-8.5 → Setting → Optimization</span>. In our release, the form includes Running mode, max_children, start_servers, min_spare_servers and max_spare_servers.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=289" target="_blank" title="">php-fpm-optimization-20261014.jpg</a> (Size: 203.89 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The native PHP Optimization screen shows the tested dynamic-pool values.</span><br />
<br />
The lab changes were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>pm = dynamic
pm.max_children = 8
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4</code></div></div>Previously the pool used max_children 80, start_servers 10, min_spare_servers 10 and max_spare_servers 30. The form's RAM presets and approximate per-worker memory guidance cannot replace your application's measurements.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What each setting does</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">pm.max_children:</span> the pool's simultaneous request-worker limit. Requests can queue when all workers are busy.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">pm.start_servers:</span> initial children for dynamic mode.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">pm.min_spare_servers:</span> desired minimum idle children in dynamic mode.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">pm.max_spare_servers:</span> desired maximum idle children in dynamic mode.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">static mode:</span> keeps a fixed worker count; plan its persistent memory use.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">ondemand mode:</span> spawns workers when needed; startup behavior and idle settings differ from dynamic mode.<br />
</li>
</ul>
Raising workers cannot make slow SQL or external APIs fast, and can overload shared resources. Lowering workers can reduce idle memory but increase queueing under traffic.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Back up, validate and reload</span><br />
We backed up /www/server/php/85/etc/php-fpm.conf before editing it through SSH, then ran:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div>Configuration validation passed. The native screen was inspected afterwards and reflected the saved values. For a UI change, use its Save action and verify the resulting configuration and service state; our test applied the changes through SSH rather than claiming we clicked Save in the UI.<br />
<br />
A configuration test proves syntax, not application behavior. Keep the backup and a working SSH recovery route. Restore it and reload if meaningful requests fail or monitoring shows unacceptable queueing/resource use.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">7. Compare the same workload honestly</span><br />
After 20 warmup requests, each measured phase used 20 requests at concurrency 2:<ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Before:</span> 20/20 HTTP 200; median TTFB 173 ms; sample p95 189 ms; 12 sampled children; aggregate child PSS about 113MiB.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">After:</span> 20/20 HTTP 200; median TTFB 180 ms; sample p95 196 ms; 4 sampled children; aggregate child PSS about 72MiB.<br />
</li>
</ul>
The smaller pool used less aggregate child memory in this snapshot. It did not make this workload faster. The small latency difference can include normal variability, and 20 requests provide limited tail-latency evidence. We did not establish maximum throughput or prove eight workers fits production peak traffic.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">8. Monitor queues and real traffic before a production decision</span><br />
Inspect PHP-FPM status, listen-queue behavior, slow requests, memory pressure, CPU saturation and database activity under a representative bounded load. Keep status endpoints private. Increase a limit only when evidence shows workers are the bottleneck and the server has resources for them.<br />
<br />
Do not use PHP memory_limit multiplied by worker count as an exact process-memory measurement. Keep application errors and OOM events in view, and test expensive pages as well as the homepage.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://www.php.net/manual/en/install.fpm.configuration.php" target="_blank" rel="noopener" class="mycode_url">Official PHP-FPM configuration documentation</a>.<br />
<span style="font-style: italic;" class="mycode_i">AdminsForum performance series. Original pool configuration retained at /www/backup/af-performance-20261014/php85-fpm-before.conf in the lab; do not publish your own private configuration values.</span>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Use Composer with PHP 8.5 in aaPanel and Verify Dependencies]]></title>
			<link>https://adminsforum.com/Thread-guide-use-composer-with-php-8-5-in-aapanel-and-verify-dependencies</link>
			<pubDate>Wed, 14 Oct 2026 02:50:32 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-use-composer-with-php-8-5-in-aapanel-and-verify-dependencies</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Use the PHP binary required by your project when running Composer on aaPanel.</span> Check Composer's version first, run dependency operations as the website user in the correct directory, and verify the generated autoloader. A panel message saying a command was sent is not proof that dependencies installed successfully.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span><br />
Ubuntu 22.04, aaPanel 8.0.7 Free Edition and PHP 8.5.11. Our lab initially had Composer 2.0.14, which produced deprecation warnings with PHP 8.5. We backed up its PHAR, updated through the official stable self-update channel to <span style="font-weight: bold;" class="mycode_b">2.10.3</span>, then installed <span style="font-weight: bold;" class="mycode_b">psr/log 3.0.2</span> as user www in a separate non-public directory. Autoload and platform-requirement checks passed. A subsequent install from composer.lock reported nothing to install, update or remove.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Inspect the panel controls and find your runtime</span><br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → Conf → Composer</span>. Our interface exposes PHP, command parameters, source, execution user and directory controls. Its version field was blank and the PHP selector offered Auto. Submitting composer --version returned <span style="font-weight: bold;" class="mycode_b">Command has been sent!</span> without command output in this screen.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=162" target="_blank" title="">composer-panel-controls-20261013.jpg</a> (Size: 196.61 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Inspected Composer controls. This screenshot does not prove that the submitted command completed.</span><br />
<br />
For a verifiable first test we used SSH instead. Sign into your own server with an authorized SSH account. The commands below are for our aaPanel PHP 8.5 layout; confirm the installed paths before copying them. A site's PHP handler and the shell's plain php command can point to different runtimes.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -v
command -v composer
/www/server/php/85/bin/php /usr/bin/composer --version</code></div></div>The first checks PHP, the second finds Composer and the third executes that PHAR with the chosen PHP binary. Our Composer location was /usr/bin/composer. Use the location reported by your own server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Update an old Composer installation carefully</span><br />
Composer 2.0.14 was the observed lab version, not a recommended version. Before updating a shared installation, record its path/version and preserve a private copy. Our administrator used:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>install -d -m 700 /root/af-composer-backups
cp -p /usr/bin/composer /root/af-composer-backups/composer-2.0.14-before-20261013.phar
/www/server/php/85/bin/php /usr/bin/composer self-update --stable --no-interaction</code></div></div>These commands require administrative access and affect the shared Composer executable. They do not update every project's dependencies. We retained the old executable for recovery, but did not test restoring it. Recheck --version after the update; ours reported 2.10.3. Do not hard-code today's version as an evergreen latest-version claim.<br />
<br />
If self-update is unavailable for your installation method, use the <a href="https://getcomposer.org/download/" target="_blank" rel="noopener" class="mycode_url">official Composer download instructions</a> and their current installer-verification procedure rather than copying an old installer checksum.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Create an isolated project directory</span><br />
Our test directory was <span style="font-weight: bold;" class="mycode_b">/www/af-composer-lab</span>, outside the websites' document roots. We created it with www ownership and 750 permissions:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>install -d -o www -g www -m 750 /www/af-composer-lab</code></div></div>Check the correct website user/group on your server. This preparation uses administrative access; the dependency operation itself runs as www. No root-owned website dependency tree or public diagnostic endpoint was needed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Install one small test dependency</span><br />
We used psr/log, a logging-interface package from the official Composer registry. It is a library test, not a complete website application:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>runuser -u www -- env COMPOSER_HOME=/www/af-composer-lab/.composer /www/server/php/85/bin/php /usr/bin/composer --working-dir=/www/af-composer-lab require 'psr/log:^3.0' --no-scripts --no-plugins --prefer-dist --no-interaction</code></div></div>COMPOSER_HOME keeps this test's Composer configuration/cache separate. --working-dir selects the exact project. We disabled scripts and plugins for the small test; do not assume those flags are suitable for every real application, because some projects require them.<br />
<br />
The actual output created composer.json, locked psr/log at 3.0.2, extracted the package and generated autoload files. aaPanel File Manager then showed composer.json, composer.lock and vendor with www ownership.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=163" target="_blank" title="">composer-project-files-20261013.jpg</a> (Size: 200.48 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual files produced in the isolated project directory. verify.php was our additional CLI-only test file.</span><br />
<br />
Open composer.json in File Manager to inspect it without changing anything. Our generated manifest contains psr/log with the ^3.0 requirement.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=164" target="_blank" title="">composer-manifest-20261013.jpg</a> (Size: 184.15 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The generated dependency requirement. composer.lock records the resolved version separately.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Verify autoloading and platform requirements</span><br />
For the rehearsal we created a non-public verify.php containing:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>&lt;?php
require '/www/af-composer-lab/vendor/autoload.php';
echo 'PHP: ', PHP_VERSION, PHP_EOL;
echo 'psr/log: ', ComposerInstalledVersions::getPrettyVersion('psr/log'), PHP_EOL;
echo 'LoggerInterface autoload: ', interface_exists(PsrLogLoggerInterface::class) ? 'PASS' : 'FAIL', PHP_EOL;</code></div></div>Run it with the same runtime and user:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>runuser -u www -- /www/server/php/85/bin/php /www/af-composer-lab/verify.php</code></div></div>Our actual output was:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP: 8.5.11
psr/log: 3.0.2
LoggerInterface autoload: PASS</code></div></div><br />
We also ran check-platform-reqs in that directory using the same PHP binary. It reported <span style="font-weight: bold;" class="mycode_b">php 8.5.11 success</span>. This verifies the requirements of the installed sample, not every possible PHP extension or a website's web runtime.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Confirm installation from the lock file</span><br />
We repeated an install in the same project:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>runuser -u www -- env COMPOSER_HOME=/www/af-composer-lab/.composer /www/server/php/85/bin/php /usr/bin/composer --working-dir=/www/af-composer-lab install --no-scripts --no-plugins --no-interaction</code></div></div>It read the lock file, verified platform compatibility and reported <span style="font-weight: bold;" class="mycode_b">Nothing to install, update or remove</span>. Keep an application's committed lock file with its deployment workflow. Deliberately resolving new dependency versions is a separate change from reproducing the locked installation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Wrong PHP version:</span> inspect the binary path used by the command, not only the site's panel setting.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Permission failure:</span> check ownership and the chosen working directory. Avoid solving it by running all dependency operations as root.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Missing extension:</span> read the requirement error and enable the needed extension for the runtime that actually executes Composer. Do not bypass platform checks to declare success.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Old-tool warnings:</span> check Composer's version and installation method. Back up and verify an update before changing projects.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Panel says command sent:</span> inspect execution output and generated files. Our verified dependency operation used SSH, not an assumed successful panel command.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Scope and final lab state</span><br />
Composer updated; isolated sample and lock file retained; autoload/platform checks passed. Existing Git demo files, WordPress and mail projects were not used as dependency destinations. No full framework deployment or browser-based PHP application test is claimed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://getcomposer.org/doc/03-cli.md" target="_blank" rel="noopener" class="mycode_url">Official Composer command documentation</a>.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Use the PHP binary required by your project when running Composer on aaPanel.</span> Check Composer's version first, run dependency operations as the website user in the correct directory, and verify the generated autoloader. A panel message saying a command was sent is not proof that dependencies installed successfully.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested environment</span><br />
Ubuntu 22.04, aaPanel 8.0.7 Free Edition and PHP 8.5.11. Our lab initially had Composer 2.0.14, which produced deprecation warnings with PHP 8.5. We backed up its PHAR, updated through the official stable self-update channel to <span style="font-weight: bold;" class="mycode_b">2.10.3</span>, then installed <span style="font-weight: bold;" class="mycode_b">psr/log 3.0.2</span> as user www in a separate non-public directory. Autoload and platform-requirement checks passed. A subsequent install from composer.lock reported nothing to install, update or remove.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Inspect the panel controls and find your runtime</span><br />
In aaPanel open <span style="font-weight: bold;" class="mycode_b">Website → Conf → Composer</span>. Our interface exposes PHP, command parameters, source, execution user and directory controls. Its version field was blank and the PHP selector offered Auto. Submitting composer --version returned <span style="font-weight: bold;" class="mycode_b">Command has been sent!</span> without command output in this screen.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=162" target="_blank" title="">composer-panel-controls-20261013.jpg</a> (Size: 196.61 KB / Downloads: 9)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Inspected Composer controls. This screenshot does not prove that the submitted command completed.</span><br />
<br />
For a verifiable first test we used SSH instead. Sign into your own server with an authorized SSH account. The commands below are for our aaPanel PHP 8.5 layout; confirm the installed paths before copying them. A site's PHP handler and the shell's plain php command can point to different runtimes.<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -v
command -v composer
/www/server/php/85/bin/php /usr/bin/composer --version</code></div></div>The first checks PHP, the second finds Composer and the third executes that PHAR with the chosen PHP binary. Our Composer location was /usr/bin/composer. Use the location reported by your own server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Update an old Composer installation carefully</span><br />
Composer 2.0.14 was the observed lab version, not a recommended version. Before updating a shared installation, record its path/version and preserve a private copy. Our administrator used:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>install -d -m 700 /root/af-composer-backups
cp -p /usr/bin/composer /root/af-composer-backups/composer-2.0.14-before-20261013.phar
/www/server/php/85/bin/php /usr/bin/composer self-update --stable --no-interaction</code></div></div>These commands require administrative access and affect the shared Composer executable. They do not update every project's dependencies. We retained the old executable for recovery, but did not test restoring it. Recheck --version after the update; ours reported 2.10.3. Do not hard-code today's version as an evergreen latest-version claim.<br />
<br />
If self-update is unavailable for your installation method, use the <a href="https://getcomposer.org/download/" target="_blank" rel="noopener" class="mycode_url">official Composer download instructions</a> and their current installer-verification procedure rather than copying an old installer checksum.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Create an isolated project directory</span><br />
Our test directory was <span style="font-weight: bold;" class="mycode_b">/www/af-composer-lab</span>, outside the websites' document roots. We created it with www ownership and 750 permissions:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>install -d -o www -g www -m 750 /www/af-composer-lab</code></div></div>Check the correct website user/group on your server. This preparation uses administrative access; the dependency operation itself runs as www. No root-owned website dependency tree or public diagnostic endpoint was needed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Install one small test dependency</span><br />
We used psr/log, a logging-interface package from the official Composer registry. It is a library test, not a complete website application:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>runuser -u www -- env COMPOSER_HOME=/www/af-composer-lab/.composer /www/server/php/85/bin/php /usr/bin/composer --working-dir=/www/af-composer-lab require 'psr/log:^3.0' --no-scripts --no-plugins --prefer-dist --no-interaction</code></div></div>COMPOSER_HOME keeps this test's Composer configuration/cache separate. --working-dir selects the exact project. We disabled scripts and plugins for the small test; do not assume those flags are suitable for every real application, because some projects require them.<br />
<br />
The actual output created composer.json, locked psr/log at 3.0.2, extracted the package and generated autoload files. aaPanel File Manager then showed composer.json, composer.lock and vendor with www ownership.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=163" target="_blank" title="">composer-project-files-20261013.jpg</a> (Size: 200.48 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Actual files produced in the isolated project directory. verify.php was our additional CLI-only test file.</span><br />
<br />
Open composer.json in File Manager to inspect it without changing anything. Our generated manifest contains psr/log with the ^3.0 requirement.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=164" target="_blank" title="">composer-manifest-20261013.jpg</a> (Size: 184.15 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The generated dependency requirement. composer.lock records the resolved version separately.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Verify autoloading and platform requirements</span><br />
For the rehearsal we created a non-public verify.php containing:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>&lt;?php
require '/www/af-composer-lab/vendor/autoload.php';
echo 'PHP: ', PHP_VERSION, PHP_EOL;
echo 'psr/log: ', ComposerInstalledVersions::getPrettyVersion('psr/log'), PHP_EOL;
echo 'LoggerInterface autoload: ', interface_exists(PsrLogLoggerInterface::class) ? 'PASS' : 'FAIL', PHP_EOL;</code></div></div>Run it with the same runtime and user:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>runuser -u www -- /www/server/php/85/bin/php /www/af-composer-lab/verify.php</code></div></div>Our actual output was:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>PHP: 8.5.11
psr/log: 3.0.2
LoggerInterface autoload: PASS</code></div></div><br />
We also ran check-platform-reqs in that directory using the same PHP binary. It reported <span style="font-weight: bold;" class="mycode_b">php 8.5.11 success</span>. This verifies the requirements of the installed sample, not every possible PHP extension or a website's web runtime.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Confirm installation from the lock file</span><br />
We repeated an install in the same project:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>runuser -u www -- env COMPOSER_HOME=/www/af-composer-lab/.composer /www/server/php/85/bin/php /usr/bin/composer --working-dir=/www/af-composer-lab install --no-scripts --no-plugins --no-interaction</code></div></div>It read the lock file, verified platform compatibility and reported <span style="font-weight: bold;" class="mycode_b">Nothing to install, update or remove</span>. Keep an application's committed lock file with its deployment workflow. Deliberately resolving new dependency versions is a separate change from reproducing the locked installation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Wrong PHP version:</span> inspect the binary path used by the command, not only the site's panel setting.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Permission failure:</span> check ownership and the chosen working directory. Avoid solving it by running all dependency operations as root.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Missing extension:</span> read the requirement error and enable the needed extension for the runtime that actually executes Composer. Do not bypass platform checks to declare success.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Old-tool warnings:</span> check Composer's version and installation method. Back up and verify an update before changing projects.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Panel says command sent:</span> inspect execution output and generated files. Our verified dependency operation used SSH, not an assumed successful panel command.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Scope and final lab state</span><br />
Composer updated; isolated sample and lock file retained; autoload/platform checks passed. Existing Git demo files, WordPress and mail projects were not used as dependency destinations. No full framework deployment or browser-based PHP application test is claimed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://getcomposer.org/doc/03-cli.md" target="_blank" rel="noopener" class="mycode_url">Official Composer command documentation</a>.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install PHP Intl in aaPanel and Fix Missing Intl Errors]]></title>
			<link>https://adminsforum.com/Thread-guide-install-php-intl-in-aapanel-and-fix-missing-intl-errors</link>
			<pubDate>Tue, 13 Oct 2026 23:32:17 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-php-intl-in-aapanel-and-fix-missing-intl-errors</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">To enable Intl in aaPanel, open the PHP version used by your website, choose Install extensions, install intl, and check the loaded-module list after the task completes.</span> This addresses a missing extension; it does not resolve every application error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested setup</span><br />
Ubuntu 22.04, aaPanel 8.0.7 Free Edition, PHP 8.5.11. We installed Intl in our lab using aaPanel's official PHP manager. The installation log reported success and a PHP-FPM reload; the refreshed extension list showed Uninstall, and the PHP information screen included intl under Loaded. These screenshots document that test. A separate website request and command-line test were not performed in this rehearsal.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What is Intl used for?</span><br />
Intl provides internationalization functions. For example, NumberFormatter formats a number or currency according to a locale. Some applications require ext-intl and may report that it is missing, or show a class-not-found error for NumberFormatter. Check the application's requirements before adding extensions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Find the PHP version your website uses</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Website</span>, select the relevant site's settings and check its PHP version. Record it before opening App Store. A server can have several PHP versions installed: an extension added to PHP 8.5 does not automatically become available in PHP 8.4.<br />
<br />
If the website uses OpenLiteSpeed, also check its configured PHP handler. Its runtime can differ from the PHP-FPM version managed here. Do not change a working site's PHP version just to match these screenshots.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the correct PHP manager</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store</span>, search for PHP, find the installed version used by the website and click <span style="font-weight: bold;" class="mycode_b">Setting</span>. Select <span style="font-weight: bold;" class="mycode_b">Install extensions</span>. Find the row named <span style="font-weight: bold;" class="mycode_b">intl</span>. The search field can narrow the list; allow the result to refresh.<br />
<br />
If Intl already shows an installed status and an Uninstall action, skip installation and proceed to verification. Do not uninstall it as a troubleshooting shortcut.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Install Intl and follow the task</span><br />
Click <span style="font-weight: bold;" class="mycode_b">Install</span> on the intl row and confirm the installation. The row changes to <span style="font-weight: bold;" class="mycode_b">Installing...</span>. Open that status link to inspect the task log. Compilation produces many lines and may take several minutes. Do not submit the same installation repeatedly or restart the panel while the build is progressing.<br />
<br />
In our test the log ended with a successful build, shared-extension installation and <span style="font-weight: bold;" class="mycode_b">Reload service php-fpm done</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=146" target="_blank" title="">php-intl-build-success-20261013.jpg</a> (Size: 224.67 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Completed installer log from the PHP 8.5 lab. A queued task alone is not proof of success.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Refresh and verify the installed extension</span><br />
Return to Install extensions and click <span style="font-weight: bold;" class="mycode_b">Refresh List</span>. Wait for the loading message to disappear. In our lab the intl row changed from Install to <span style="font-weight: bold;" class="mycode_b">Uninstall</span>, confirming the manager's installed status.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=147" target="_blank" title="">php-intl-installed-20261013.jpg</a> (Size: 238.12 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Intl installed for PHP 8.5. Leave the Uninstall control untouched.</span><br />
<br />
Select <span style="font-weight: bold;" class="mycode_b">phpinfo</span> in the same manager. Check the version and the <span style="font-weight: bold;" class="mycode_b">Loaded</span> list. Our screen reports <span style="font-weight: bold;" class="mycode_b">8.5.11</span> and includes <span style="font-weight: bold;" class="mycode_b">intl</span>. This checks the manager's PHP runtime; verify the website separately if its error remains.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=148" target="_blank" title="">php-intl-loaded-20261013.jpg</a> (Size: 288.85 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The PHP information screen lists intl among loaded extensions.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Recheck the application</span><br />
Reload the application's requirements check or the page that originally failed. Confirm that its PHP version matches the version you modified. If you have SSH access, this optional command checks the aaPanel PHP 8.5 CLI binary:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -r 'echo PHP_VERSION, PHP_EOL; var_export(extension_loaded("intl")); echo PHP_EOL;'</code></div></div>A loaded extension returns true. Replace 85 with your installed version's directory. Running plain php may check a different system binary. This command is an additional check for readers, not output captured in our rehearsal.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">The task fails:</span> read the first actual error in the log. A compiler/dependency error needs its own fix; a final queue message does not explain the cause. Include the PHP version and relevant error when asking for support.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Installed but still missing:</span> check the website's PHP version, PHP handler and application's requirements screen. The CLI and web runtime may differ.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Duplicate loading warning:</span> inspect the relevant configuration for repeated extension entries. Avoid adding extension=intl blindly after the manager has already configured it.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">No intl row:</span> refresh the official app/extension list and check support for your PHP version. Installing the operating system's php-intl package may affect system PHP rather than aaPanel's PHP installation.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Success checklist</span><br />
The installer finishes successfully, the intl row shows installed, the correct runtime lists intl, and the application's missing-extension check clears. Only the first three were directly verified in this lab rehearsal.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://www.php.net/manual/en/class.numberformatter.php" target="_blank" rel="noopener" class="mycode_url">PHP NumberFormatter documentation</a> and <a href="https://www.php.net/manual/en/intl.installation.php" target="_blank" rel="noopener" class="mycode_url">PHP Intl installation documentation</a>.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Need help?</span> Post your aaPanel version, website PHP version and the relevant installation error in PHP &amp; Extensions Support. Remove credentials and private tokens from screenshots or logs.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">To enable Intl in aaPanel, open the PHP version used by your website, choose Install extensions, install intl, and check the loaded-module list after the task completes.</span> This addresses a missing extension; it does not resolve every application error.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Tested setup</span><br />
Ubuntu 22.04, aaPanel 8.0.7 Free Edition, PHP 8.5.11. We installed Intl in our lab using aaPanel's official PHP manager. The installation log reported success and a PHP-FPM reload; the refreshed extension list showed Uninstall, and the PHP information screen included intl under Loaded. These screenshots document that test. A separate website request and command-line test were not performed in this rehearsal.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What is Intl used for?</span><br />
Intl provides internationalization functions. For example, NumberFormatter formats a number or currency according to a locale. Some applications require ext-intl and may report that it is missing, or show a class-not-found error for NumberFormatter. Check the application's requirements before adding extensions.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Find the PHP version your website uses</span><br />
Open <span style="font-weight: bold;" class="mycode_b">Website</span>, select the relevant site's settings and check its PHP version. Record it before opening App Store. A server can have several PHP versions installed: an extension added to PHP 8.5 does not automatically become available in PHP 8.4.<br />
<br />
If the website uses OpenLiteSpeed, also check its configured PHP handler. Its runtime can differ from the PHP-FPM version managed here. Do not change a working site's PHP version just to match these screenshots.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the correct PHP manager</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store</span>, search for PHP, find the installed version used by the website and click <span style="font-weight: bold;" class="mycode_b">Setting</span>. Select <span style="font-weight: bold;" class="mycode_b">Install extensions</span>. Find the row named <span style="font-weight: bold;" class="mycode_b">intl</span>. The search field can narrow the list; allow the result to refresh.<br />
<br />
If Intl already shows an installed status and an Uninstall action, skip installation and proceed to verification. Do not uninstall it as a troubleshooting shortcut.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Install Intl and follow the task</span><br />
Click <span style="font-weight: bold;" class="mycode_b">Install</span> on the intl row and confirm the installation. The row changes to <span style="font-weight: bold;" class="mycode_b">Installing...</span>. Open that status link to inspect the task log. Compilation produces many lines and may take several minutes. Do not submit the same installation repeatedly or restart the panel while the build is progressing.<br />
<br />
In our test the log ended with a successful build, shared-extension installation and <span style="font-weight: bold;" class="mycode_b">Reload service php-fpm done</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=146" target="_blank" title="">php-intl-build-success-20261013.jpg</a> (Size: 224.67 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Completed installer log from the PHP 8.5 lab. A queued task alone is not proof of success.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Refresh and verify the installed extension</span><br />
Return to Install extensions and click <span style="font-weight: bold;" class="mycode_b">Refresh List</span>. Wait for the loading message to disappear. In our lab the intl row changed from Install to <span style="font-weight: bold;" class="mycode_b">Uninstall</span>, confirming the manager's installed status.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=147" target="_blank" title="">php-intl-installed-20261013.jpg</a> (Size: 238.12 KB / Downloads: 5)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Intl installed for PHP 8.5. Leave the Uninstall control untouched.</span><br />
<br />
Select <span style="font-weight: bold;" class="mycode_b">phpinfo</span> in the same manager. Check the version and the <span style="font-weight: bold;" class="mycode_b">Loaded</span> list. Our screen reports <span style="font-weight: bold;" class="mycode_b">8.5.11</span> and includes <span style="font-weight: bold;" class="mycode_b">intl</span>. This checks the manager's PHP runtime; verify the website separately if its error remains.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=148" target="_blank" title="">php-intl-loaded-20261013.jpg</a> (Size: 288.85 KB / Downloads: 4)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The PHP information screen lists intl among loaded extensions.</span><br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Recheck the application</span><br />
Reload the application's requirements check or the page that originally failed. Confirm that its PHP version matches the version you modified. If you have SSH access, this optional command checks the aaPanel PHP 8.5 CLI binary:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -r 'echo PHP_VERSION, PHP_EOL; var_export(extension_loaded("intl")); echo PHP_EOL;'</code></div></div>A loaded extension returns true. Replace 85 with your installed version's directory. Running plain php may check a different system binary. This command is an additional check for readers, not output captured in our rehearsal.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">The task fails:</span> read the first actual error in the log. A compiler/dependency error needs its own fix; a final queue message does not explain the cause. Include the PHP version and relevant error when asking for support.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Installed but still missing:</span> check the website's PHP version, PHP handler and application's requirements screen. The CLI and web runtime may differ.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Duplicate loading warning:</span> inspect the relevant configuration for repeated extension entries. Avoid adding extension=intl blindly after the manager has already configured it.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">No intl row:</span> refresh the official app/extension list and check support for your PHP version. Installing the operating system's php-intl package may affect system PHP rather than aaPanel's PHP installation.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Success checklist</span><br />
The installer finishes successfully, the intl row shows installed, the correct runtime lists intl, and the application's missing-extension check clears. Only the first three were directly verified in this lab rehearsal.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Reference:</span> <a href="https://www.php.net/manual/en/class.numberformatter.php" target="_blank" rel="noopener" class="mycode_url">PHP NumberFormatter documentation</a> and <a href="https://www.php.net/manual/en/intl.installation.php" target="_blank" rel="noopener" class="mycode_url">PHP Intl installation documentation</a>.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Need help?</span> Post your aaPanel version, website PHP version and the relevant installation error in PHP &amp; Extensions Support. Remove credentials and private tokens from screenshots or logs.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Increase WordPress PHP Upload Limits in aaPanel to 64 MB]]></title>
			<link>https://adminsforum.com/Thread-guide-increase-wordpress-php-upload-limits-in-aapanel-to-64-mb</link>
			<pubDate>Tue, 13 Oct 2026 09:48:21 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-increase-wordpress-php-upload-limits-in-aapanel-to-64-mb</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Open the settings for the PHP version used by your website, change Limit of upload, then give post_max_size extra room for the whole request. Verify the limit in WordPress and test a fresh upload. Changing an unused PHP version or the CLI configuration does not fix the website's upload limit.<br />
<br />
Our aaPanel 8.0.6 lab used Nginx 1.30.5, PHP-FPM 8.5.11 and WordPress 7.1.3. We raised the displayed WordPress limit from 50 MB to 64 MB, set the POST limit to 72M, corrected a PHP 8.5 memory-cap warning and completed a fresh branded JPEG upload. Screenshots are original AdminsForum lab captures.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Check which PHP handles the website</span><br />
In aaPanel, find the website's selected PHP version. In WordPress, open Tools → Site Health → Info → Server. Record the PHP version and PHP SAPI. Our website reported fpm-fcgi, so we changed the regular PHP-8.5 manager.<br />
<br />
OpenLiteSpeed's litespeed SAPI uses a separate lsphp installation. Its settings can differ even when the version number matches. Our earlier OpenLiteSpeed test had an 8M POST limit and therefore an 8 MB effective upload limit. Use <a href="https://adminsforum.com/Thread-guide-check-openlitespeed-php-version-and-extensions-in-aapanel" target="_blank" rel="noopener" class="mycode_url">the separate-runtime guide</a> before changing that installation. The verified 64 MB screenshots in this post are from PHP-FPM; they are not proof that an unrelated lsphp installation changed automatically.<br />
<br />
Back up the applicable PHP and web-server configuration before editing. Note that a version-wide PHP change can affect every website using that version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Record the current upload limit</span><br />
Open App Store → Installed → PHP-8.5 → Setting. Choose Limit of upload. The lab originally showed 50 MB. WordPress Media → Add Media File also reported 50 MB.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=105" target="_blank" title="">batch11-php-limit-before-branded.jpg</a> (Size: 64.7 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
For your site, use its actual version rather than following the number in our example blindly. Choose a limit appropriate to the files and server resources you need.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Set the file limit and POST headroom</span><br />
On Limit of upload, enter 64 and click Save. Wait for completion. Then open Configuration and review upload_max_filesize and post_max_size. Our panel's upload-limit action set both to 64M; we changed post_max_size to 72M and saved again.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=106" target="_blank" title="">batch11-php-limit-config-branded.jpg</a> (Size: 120.43 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
The file limit applies to one uploaded file. POST size applies to the complete request, including form fields and upload overhead. Keep POST size above the intended file size. Our resulting settings were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>upload_max_filesize = 64M
post_max_size = 72M
memory_limit = 128M</code></div></div><br />
These are tested example values, not a universal tuning preset. A large high-resolution image may require much more processing memory than its compressed file size suggests.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Handle the PHP 8.5 memory-cap warning if present</span><br />
Our first upload attempt exposed a warning: WordPress tried to raise memory_limit to 256M for administration, but max_memory_limit capped it at 128M. PHP 8.5 introduced this startup-only ceiling, so changing an application-side memory preference alone may not solve it.<br />
<br />
We preserved the original ini file, changed the active PHP-FPM ini directive to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>max_memory_limit = 256M</code></div></div><br />
The normal frontend memory_limit remained 128M. This allowed WordPress's administration request to use 256M without setting unlimited memory. We also set display_errors = Off while keeping log_errors = On, so diagnostics are logged rather than inserted into public pages or upload responses. The configuration screenshot above was taken before that final error-display change.<br />
<br />
In aaPanel, use the matching PHP manager's Configuration file editor for directives absent from its simple form. Make only the intended change and preserve the rest of the file. The lab's relevant ini path was /www/server/php/85/etc/php.ini; confirm your own loaded path first.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Validate and reload the correct PHP service</span><br />
We checked the PHP-FPM configuration successfully, then reloaded PHP-FPM 8.5. The exact service-specific commands used in this lab were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div><br />
Inspect the test result before reloading. If it fails, correct the syntax or restore the saved configuration. Do not reload a different PHP version and assume the website received the change. An lsphp website needs its own appropriate worker/service reload.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify an actual WordPress request</span><br />
Refresh Tools → Site Health → Info → Server. Our website reported upload_max_filesize 64M, post_max_size 72M, frontend memory 128M and administration memory 256M.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=107" target="_blank" title="">batch11-php-limit-runtime-branded.jpg</a> (Size: 112.34 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
Then reopen Media → Add Media File. WordPress showed Maximum upload file size: 64 MB. We uploaded a fresh original branded JPEG successfully; the upload finished and offered Edit and Copy URL actions without the earlier memory warning.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=108" target="_blank" title="">batch11-php-upload-pass-branded.jpg</a> (Size: 89.56 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
We verified the settings and a normal image upload. We did not test a file exactly at the 64 MB boundary, so this post does not claim a maximum-size stress test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">If uploads still fail</span><ul class="mycode_list"><li>The old limit remains: confirm the actual PHP handler, loaded ini and fresh request after the relevant reload.<br />
</li>
<li>413 Request Entity Too Large: inspect the applicable web-server/reverse-proxy request-body limit; changing PHP alone may not change every upstream layer.<br />
</li>
<li>POST data disappears or the upload is empty: check the whole-request POST limit and temporary upload directory.<br />
</li>
<li>Upload reaches the server but image processing fails: inspect logs, memory ceilings, image dimensions, filesystem permissions and the image library.<br />
</li>
</ul>
<br />
Keep the previous values and configuration backup for rollback. Check application behavior after reverting and reloading as carefully as after increasing the limit.<br />
<br />
Reference: <a href="https://www.php.net/manual/en/ini.core.php" target="_blank" rel="noopener" class="mycode_url">PHP resource and upload directives</a>. © AdminsForum.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Open the settings for the PHP version used by your website, change Limit of upload, then give post_max_size extra room for the whole request. Verify the limit in WordPress and test a fresh upload. Changing an unused PHP version or the CLI configuration does not fix the website's upload limit.<br />
<br />
Our aaPanel 8.0.6 lab used Nginx 1.30.5, PHP-FPM 8.5.11 and WordPress 7.1.3. We raised the displayed WordPress limit from 50 MB to 64 MB, set the POST limit to 72M, corrected a PHP 8.5 memory-cap warning and completed a fresh branded JPEG upload. Screenshots are original AdminsForum lab captures.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Check which PHP handles the website</span><br />
In aaPanel, find the website's selected PHP version. In WordPress, open Tools → Site Health → Info → Server. Record the PHP version and PHP SAPI. Our website reported fpm-fcgi, so we changed the regular PHP-8.5 manager.<br />
<br />
OpenLiteSpeed's litespeed SAPI uses a separate lsphp installation. Its settings can differ even when the version number matches. Our earlier OpenLiteSpeed test had an 8M POST limit and therefore an 8 MB effective upload limit. Use <a href="https://adminsforum.com/Thread-guide-check-openlitespeed-php-version-and-extensions-in-aapanel" target="_blank" rel="noopener" class="mycode_url">the separate-runtime guide</a> before changing that installation. The verified 64 MB screenshots in this post are from PHP-FPM; they are not proof that an unrelated lsphp installation changed automatically.<br />
<br />
Back up the applicable PHP and web-server configuration before editing. Note that a version-wide PHP change can affect every website using that version.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Record the current upload limit</span><br />
Open App Store → Installed → PHP-8.5 → Setting. Choose Limit of upload. The lab originally showed 50 MB. WordPress Media → Add Media File also reported 50 MB.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=105" target="_blank" title="">batch11-php-limit-before-branded.jpg</a> (Size: 64.7 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
For your site, use its actual version rather than following the number in our example blindly. Choose a limit appropriate to the files and server resources you need.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Set the file limit and POST headroom</span><br />
On Limit of upload, enter 64 and click Save. Wait for completion. Then open Configuration and review upload_max_filesize and post_max_size. Our panel's upload-limit action set both to 64M; we changed post_max_size to 72M and saved again.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=106" target="_blank" title="">batch11-php-limit-config-branded.jpg</a> (Size: 120.43 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
The file limit applies to one uploaded file. POST size applies to the complete request, including form fields and upload overhead. Keep POST size above the intended file size. Our resulting settings were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>upload_max_filesize = 64M
post_max_size = 72M
memory_limit = 128M</code></div></div><br />
These are tested example values, not a universal tuning preset. A large high-resolution image may require much more processing memory than its compressed file size suggests.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Handle the PHP 8.5 memory-cap warning if present</span><br />
Our first upload attempt exposed a warning: WordPress tried to raise memory_limit to 256M for administration, but max_memory_limit capped it at 128M. PHP 8.5 introduced this startup-only ceiling, so changing an application-side memory preference alone may not solve it.<br />
<br />
We preserved the original ini file, changed the active PHP-FPM ini directive to:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>max_memory_limit = 256M</code></div></div><br />
The normal frontend memory_limit remained 128M. This allowed WordPress's administration request to use 256M without setting unlimited memory. We also set display_errors = Off while keeping log_errors = On, so diagnostics are logged rather than inserted into public pages or upload responses. The configuration screenshot above was taken before that final error-display change.<br />
<br />
In aaPanel, use the matching PHP manager's Configuration file editor for directives absent from its simple form. Make only the intended change and preserve the rest of the file. The lab's relevant ini path was /www/server/php/85/etc/php.ini; confirm your own loaded path first.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Validate and reload the correct PHP service</span><br />
We checked the PHP-FPM configuration successfully, then reloaded PHP-FPM 8.5. The exact service-specific commands used in this lab were:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -t
/etc/init.d/php-fpm-85 reload</code></div></div><br />
Inspect the test result before reloading. If it fails, correct the syntax or restore the saved configuration. Do not reload a different PHP version and assume the website received the change. An lsphp website needs its own appropriate worker/service reload.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify an actual WordPress request</span><br />
Refresh Tools → Site Health → Info → Server. Our website reported upload_max_filesize 64M, post_max_size 72M, frontend memory 128M and administration memory 256M.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=107" target="_blank" title="">batch11-php-limit-runtime-branded.jpg</a> (Size: 112.34 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
Then reopen Media → Add Media File. WordPress showed Maximum upload file size: 64 MB. We uploaded a fresh original branded JPEG successfully; the upload finished and offered Edit and Copy URL actions without the earlier memory warning.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=108" target="_blank" title="">batch11-php-upload-pass-branded.jpg</a> (Size: 89.56 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
We verified the settings and a normal image upload. We did not test a file exactly at the 64 MB boundary, so this post does not claim a maximum-size stress test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">If uploads still fail</span><ul class="mycode_list"><li>The old limit remains: confirm the actual PHP handler, loaded ini and fresh request after the relevant reload.<br />
</li>
<li>413 Request Entity Too Large: inspect the applicable web-server/reverse-proxy request-body limit; changing PHP alone may not change every upstream layer.<br />
</li>
<li>POST data disappears or the upload is empty: check the whole-request POST limit and temporary upload directory.<br />
</li>
<li>Upload reaches the server but image processing fails: inspect logs, memory ceilings, image dimensions, filesystem permissions and the image library.<br />
</li>
</ul>
<br />
Keep the previous values and configuration backup for rollback. Check application behavior after reverting and reloading as carefully as after increasing the limit.<br />
<br />
Reference: <a href="https://www.php.net/manual/en/ini.core.php" target="_blank" rel="noopener" class="mycode_url">PHP resource and upload directives</a>. © AdminsForum.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install Imagick for OpenLiteSpeed PHP in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-install-imagick-for-openlitespeed-php-in-aapanel</link>
			<pubDate>Tue, 13 Oct 2026 02:31:33 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-imagick-for-openlitespeed-php-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store → Installed → Openlitespeed → Setting → Install extensions</span>, select the website's lsphp version and install <span style="font-weight: bold;" class="mycode_b">imagemagick</span>. Verify the Imagick PHP extension with the matching lsphp binary and then check an actual website request.<br />
<br />
We tested this on aaPanel 8.0.6, OpenLiteSpeed 1.8.5 and lsphp 8.5.11 on our isolated Ubuntu 22.04 lab. Imagick was initially missing from lsphp, although the normal aaPanel PHP installation already had it. The lsphp installation completed and the functional image test passed on 12 October 2026.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you start</span><ul class="mycode_list"><li>Have OpenLiteSpeed installed and identify the PHP version used by the website.<br />
</li>
<li>Preserve the relevant PHP/web-server configuration and a current website backup before changing the runtime.<br />
</li>
<li>Use <a href="https://adminsforum.com/Thread-guide-check-openlitespeed-php-version-and-extensions-in-aapanel" target="_blank" rel="noopener" class="mycode_url">the lsphp runtime-check guide</a> to distinguish the separate installation and its loaded configuration file.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">1. Open the lsphp extension list</span><br />
Open the installed Openlitespeed application's Setting link. Choose <span style="font-weight: bold;" class="mycode_b">Install extensions</span> and select the correct version; ours was <span style="font-weight: bold;" class="mycode_b">PHP-85</span>. Find <span style="font-weight: bold;" class="mycode_b">imagemagick</span>, described as the Imagick graphics library.<br />
<br />
In our initial list, the row showed <span style="font-weight: bold;" class="mycode_b">Install</span>. Other extensions such as Fileinfo were already available. Install only the extension your application needs.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=92" target="_blank" title="">ols-imagick-before-branded-20261012.jpg</a> (Size: 132.79 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Start installation and wait for the result</span><br />
Click the imagemagick row's <span style="font-weight: bold;" class="mycode_b">Install</span> link. Our row changed to <span style="font-weight: bold;" class="mycode_b">Installing</span> while aaPanel ran the setup. Wait for it to finish rather than repeatedly clicking Install.<br />
<br />
After completion, the row showed the installed checkmark and an <span style="font-weight: bold;" class="mycode_b">Uninstall</span> action. This is an installation-status check, so continue with the runtime test rather than stopping at the button label.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=93" target="_blank" title="">ols-imagick-after-branded-20261012.jpg</a> (Size: 120.16 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<br />
If installation fails, inspect the task/error result before retrying. Package/build availability depends on PHP version and operating system; do not copy an extension binary from another PHP installation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Run a functional test with the lsphp binary</span><br />
In the aaPanel Terminal, this exact test was run against our lsphp 8.5 installation:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/bin/php -r 'echo "PHP: ".PHP_VERSION.PHP_EOL;echo "INI: ".php_ini_loaded_file().PHP_EOL;if(!class_exists("Imagick"))throw new Exception("Imagick is missing");echo "Imagick: ".phpversion("imagick").PHP_EOL;&#36;i=new Imagick();&#36;i-&gt;newImage(64,64,new ImagickPixel("#27ae60"));&#36;i-&gt;resizeImage(32,32,Imagick::FILTER_LANCZOS,1);&#36;i-&gt;setImageFormat("png");echo "Resize/PNG test: ".&#36;i-&gt;getImageWidth()."x".&#36;i-&gt;getImageHeight()."; bytes=".strlen(&#36;i-&gt;getImageBlob()).PHP_EOL;'</code></div></div>It creates a 64 × 64 image in memory, resizes it to 32 × 32 and encodes a PNG. It does not write an image into a public website directory. Replace the version directory with the actual one used by your installation.<br />
<br />
Our result was PHP <span style="font-weight: bold;" class="mycode_b">8.5.11</span>, Imagick <span style="font-weight: bold;" class="mycode_b">3.8.1</span>, and <span style="font-weight: bold;" class="mycode_b">Resize/PNG test: 32x32; bytes=160</span>. A different library build can produce a different byte count; the important checks are that processing succeeds, dimensions match and the encoded image is non-empty.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=94" target="_blank" title="">ols-imagick-test-branded-20261012.jpg</a> (Size: 35.16 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
The loaded configuration file reported by the binary was:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/etc/php/8.5/litespeed/php.ini</code></div></div>Use the runtime's reported path when diagnosing configuration. In this aaPanel build, the panel's path label differed from the loaded path; we did not create or edit a second ini file to match that label.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Confirm the actual website detects Imagick</span><br />
For WordPress, open <span style="font-weight: bold;" class="mycode_b">Tools → Site Health → Info → Server</span>. After switching our test site to Nginx + OpenLiteSpeed, it reported <span style="font-weight: bold;" class="mycode_b">PHP SAPI: litespeed</span> and <span style="font-weight: bold;" class="mycode_b">Is the Imagick library available? Yes</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=95" target="_blank" title="">ols-wp-server-branded-20261012.jpg</a> (Size: 109.41 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
The SAPI check matters: a CLI test from the right binary still does not prove which runtime a website request uses. If an existing application still reports the old extension list, check its selected PHP version and follow the appropriate PHP-worker/service reload procedure before testing a fresh request.<br />
<br />
We also uploaded a fresh branded JPEG through WordPress on this backend and opened its public HTTPS file successfully. That checked the upload workflow separately from the in-memory CLI image test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">If Imagick is still missing</span><ul class="mycode_list"><li>Confirm you installed it in the Openlitespeed manager for the selected lsphp version.<br />
</li>
<li>Check the binary path, loaded ini file and application-side PHP SAPI again.<br />
</li>
<li>Inspect the installation result and application errors rather than adding duplicate extension directives.<br />
</li>
<li>Recheck after the appropriate worker reload if the application was already running during installation.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Our verified result</span><br />
The lsphp extension row showed installed, Imagick 3.8.1 processed an image, and WordPress detected Imagick under litespeed SAPI. We did not change the website's upload limits or benchmark image-processing speed.<br />
<br />
Reference: <a href="https://www.php.net/manual/en/book.imagick.php" target="_blank" rel="noopener" class="mycode_url">PHP Imagick manual</a> and <a href="https://www.aapanel.com/docs/faq/multi-webserver_hosting.html" target="_blank" rel="noopener" class="mycode_url">aaPanel OpenLiteSpeed PHP management</a>. Screenshots are original AdminsForum lab captures.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
Open <span style="font-weight: bold;" class="mycode_b">App Store → Installed → Openlitespeed → Setting → Install extensions</span>, select the website's lsphp version and install <span style="font-weight: bold;" class="mycode_b">imagemagick</span>. Verify the Imagick PHP extension with the matching lsphp binary and then check an actual website request.<br />
<br />
We tested this on aaPanel 8.0.6, OpenLiteSpeed 1.8.5 and lsphp 8.5.11 on our isolated Ubuntu 22.04 lab. Imagick was initially missing from lsphp, although the normal aaPanel PHP installation already had it. The lsphp installation completed and the functional image test passed on 12 October 2026.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Before you start</span><ul class="mycode_list"><li>Have OpenLiteSpeed installed and identify the PHP version used by the website.<br />
</li>
<li>Preserve the relevant PHP/web-server configuration and a current website backup before changing the runtime.<br />
</li>
<li>Use <a href="https://adminsforum.com/Thread-guide-check-openlitespeed-php-version-and-extensions-in-aapanel" target="_blank" rel="noopener" class="mycode_url">the lsphp runtime-check guide</a> to distinguish the separate installation and its loaded configuration file.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">1. Open the lsphp extension list</span><br />
Open the installed Openlitespeed application's Setting link. Choose <span style="font-weight: bold;" class="mycode_b">Install extensions</span> and select the correct version; ours was <span style="font-weight: bold;" class="mycode_b">PHP-85</span>. Find <span style="font-weight: bold;" class="mycode_b">imagemagick</span>, described as the Imagick graphics library.<br />
<br />
In our initial list, the row showed <span style="font-weight: bold;" class="mycode_b">Install</span>. Other extensions such as Fileinfo were already available. Install only the extension your application needs.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=92" target="_blank" title="">ols-imagick-before-branded-20261012.jpg</a> (Size: 132.79 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Start installation and wait for the result</span><br />
Click the imagemagick row's <span style="font-weight: bold;" class="mycode_b">Install</span> link. Our row changed to <span style="font-weight: bold;" class="mycode_b">Installing</span> while aaPanel ran the setup. Wait for it to finish rather than repeatedly clicking Install.<br />
<br />
After completion, the row showed the installed checkmark and an <span style="font-weight: bold;" class="mycode_b">Uninstall</span> action. This is an installation-status check, so continue with the runtime test rather than stopping at the button label.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=93" target="_blank" title="">ols-imagick-after-branded-20261012.jpg</a> (Size: 120.16 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<br />
If installation fails, inspect the task/error result before retrying. Package/build availability depends on PHP version and operating system; do not copy an extension binary from another PHP installation.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Run a functional test with the lsphp binary</span><br />
In the aaPanel Terminal, this exact test was run against our lsphp 8.5 installation:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/bin/php -r 'echo "PHP: ".PHP_VERSION.PHP_EOL;echo "INI: ".php_ini_loaded_file().PHP_EOL;if(!class_exists("Imagick"))throw new Exception("Imagick is missing");echo "Imagick: ".phpversion("imagick").PHP_EOL;&#36;i=new Imagick();&#36;i-&gt;newImage(64,64,new ImagickPixel("#27ae60"));&#36;i-&gt;resizeImage(32,32,Imagick::FILTER_LANCZOS,1);&#36;i-&gt;setImageFormat("png");echo "Resize/PNG test: ".&#36;i-&gt;getImageWidth()."x".&#36;i-&gt;getImageHeight()."; bytes=".strlen(&#36;i-&gt;getImageBlob()).PHP_EOL;'</code></div></div>It creates a 64 × 64 image in memory, resizes it to 32 × 32 and encodes a PNG. It does not write an image into a public website directory. Replace the version directory with the actual one used by your installation.<br />
<br />
Our result was PHP <span style="font-weight: bold;" class="mycode_b">8.5.11</span>, Imagick <span style="font-weight: bold;" class="mycode_b">3.8.1</span>, and <span style="font-weight: bold;" class="mycode_b">Resize/PNG test: 32x32; bytes=160</span>. A different library build can produce a different byte count; the important checks are that processing succeeds, dimensions match and the encoded image is non-empty.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=94" target="_blank" title="">ols-imagick-test-branded-20261012.jpg</a> (Size: 35.16 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
The loaded configuration file reported by the binary was:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/etc/php/8.5/litespeed/php.ini</code></div></div>Use the runtime's reported path when diagnosing configuration. In this aaPanel build, the panel's path label differed from the loaded path; we did not create or edit a second ini file to match that label.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Confirm the actual website detects Imagick</span><br />
For WordPress, open <span style="font-weight: bold;" class="mycode_b">Tools → Site Health → Info → Server</span>. After switching our test site to Nginx + OpenLiteSpeed, it reported <span style="font-weight: bold;" class="mycode_b">PHP SAPI: litespeed</span> and <span style="font-weight: bold;" class="mycode_b">Is the Imagick library available? Yes</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=95" target="_blank" title="">ols-wp-server-branded-20261012.jpg</a> (Size: 109.41 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
The SAPI check matters: a CLI test from the right binary still does not prove which runtime a website request uses. If an existing application still reports the old extension list, check its selected PHP version and follow the appropriate PHP-worker/service reload procedure before testing a fresh request.<br />
<br />
We also uploaded a fresh branded JPEG through WordPress on this backend and opened its public HTTPS file successfully. That checked the upload workflow separately from the in-memory CLI image test.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">If Imagick is still missing</span><ul class="mycode_list"><li>Confirm you installed it in the Openlitespeed manager for the selected lsphp version.<br />
</li>
<li>Check the binary path, loaded ini file and application-side PHP SAPI again.<br />
</li>
<li>Inspect the installation result and application errors rather than adding duplicate extension directives.<br />
</li>
<li>Recheck after the appropriate worker reload if the application was already running during installation.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Our verified result</span><br />
The lsphp extension row showed installed, Imagick 3.8.1 processed an image, and WordPress detected Imagick under litespeed SAPI. We did not change the website's upload limits or benchmark image-processing speed.<br />
<br />
Reference: <a href="https://www.php.net/manual/en/book.imagick.php" target="_blank" rel="noopener" class="mycode_url">PHP Imagick manual</a> and <a href="https://www.aapanel.com/docs/faq/multi-webserver_hosting.html" target="_blank" rel="noopener" class="mycode_url">aaPanel OpenLiteSpeed PHP management</a>. Screenshots are original AdminsForum lab captures.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Check OpenLiteSpeed PHP Version and Extensions in aaPanel]]></title>
			<link>https://adminsforum.com/Thread-guide-check-openlitespeed-php-version-and-extensions-in-aapanel</link>
			<pubDate>Tue, 13 Oct 2026 02:25:20 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-check-openlitespeed-php-version-and-extensions-in-aapanel</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
For OpenLiteSpeed, inspect <span style="font-weight: bold;" class="mycode_b">App Store → Installed → Openlitespeed → Setting → PHP Info</span>. Select the PHP version you intend to use. OpenLiteSpeed uses a separate lsphp installation, so an extension installed through the normal PHP-8.5 manager is not proof that lsphp has it.<br />
<br />
This guide was tested on our isolated aaPanel 8.0.6 / Ubuntu 22.04 lab on 12 October 2026. The OpenLiteSpeed manager reported version 1.8.5, and both PHP installations reported PHP 8.5.11. We also checked the actual WordPress runtime after switching that test site to Nginx + OpenLiteSpeed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the website's engine and PHP version</span><br />
Open the website's configuration and check <span style="font-weight: bold;" class="mycode_b">Web Server</span> and <span style="font-weight: bold;" class="mycode_b">PHP version</span>. For our WP Toolkit site, those controls were under <span style="font-weight: bold;" class="mycode_b">WP Toolkit → Modify</span>. Do not assume that the server's default engine or a bare php command describes this particular website.<br />
<br />
If you still need to enable multiple services, see <a href="https://adminsforum.com/Thread-guide-enable-aapanel-multi-webserver-hosting-and-switch-a-website" target="_blank" rel="noopener" class="mycode_url">the tested multi-webserver installation guide</a>. Changing engines is a separate operation from checking PHP information.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the correct PHP manager</span><br />
In <span style="font-weight: bold;" class="mycode_b">App Store → Installed</span>, open the <span style="font-weight: bold;" class="mycode_b">Openlitespeed</span> row's Setting link, then choose <span style="font-weight: bold;" class="mycode_b">PHP Info</span>. We selected <span style="font-weight: bold;" class="mycode_b">PHP-85</span>. Wait for the data to finish loading: temporary empty cells or default No values are not a reliable result while the request is pending.<br />
<br />
The Basic Information section reported PHP 8.5.11 and the lsphp binary under /usr/local/lsws. Our initial capture is below.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=88" target="_blank" title="">ols-php-version-branded-20261012.jpg</a> (Size: 106.47 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Distinguish the two installations</span><br />
Our lab had:<ul class="mycode_list"><li>Normal aaPanel PHP binary: <br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php</code></div></div></li>
<li>OpenLiteSpeed PHP binary: <br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/bin/php</code></div></div></li>
</ul>
The matching 8.5.11 version numbers did not make these the same installation. Before we installed the lsphp Imagick extension, the normal aaPanel binary loaded Imagick while lsphp did not.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=89" target="_blank" title="">ols-php-compare-branded-20261012.jpg</a> (Size: 69.06 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
These comparison commands were run in CLI mode; the first label in the screenshot identifies the aaPanel PHP installation used with PHP-FPM, not an active FPM worker request. CLI settings and website settings can differ.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Verify the configuration file with the intended binary</span><br />
In the aaPanel Terminal, this read-only check prints the PHP version, loaded configuration file and selected extension availability:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/bin/php -r 'echo "PHP version: ".PHP_VERSION.PHP_EOL;echo "Loaded ini: ".php_ini_loaded_file().PHP_EOL;foreach(["exif","fileinfo","imagick","Zend OPcache"] as &#36;e)echo &#36;e.": ".(extension_loaded(&#36;e)?"loaded":"missing").PHP_EOL;'</code></div></div>Replace 85 with the version directory that actually exists on your server. Do not copy a path from another PHP version and do not create a public phpinfo.php file just to run this check.<br />
<br />
One detail mattered in our test: the panel displayed an ini path containing /php/85/litespeed/, while the lsphp binary reported the actual loaded path as:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/etc/php/8.5/litespeed/php.ini</code></div></div>Check the loaded path before editing configuration. A path label in a panel is not a reason to create a second configuration file that the runtime never reads. We did not change a php.ini setting in this walkthrough.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Check the extensions required by your application</span><br />
Scroll through PHP Info and look at the database, image-processing and file-handling sections. WordPress needs its database connection and the image/file features used by your site. Install extensions for actual application requirements rather than enabling every optional item.<br />
<br />
After our lsphp setup, the panel showed EXIF, GD, ImageMagick and Fileinfo available. Imagick was installed during a separate tested setup step; this screenshot is the resulting configuration, not a promise that every fresh lsphp installation has it by default.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=90" target="_blank" title="">ols-extensions-branded-20261012.jpg</a> (Size: 112.67 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
To install a missing lsphp extension through aaPanel, use <span style="font-weight: bold;" class="mycode_b">Openlitespeed → Install extensions</span> for the selected version. Using the normal PHP-8.5 extension manager can affect the other installation instead.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Confirm what a real website request uses</span><br />
For WordPress, open <span style="font-weight: bold;" class="mycode_b">Tools → Site Health → Info → Server</span>. After the engine switch, our WordPress page reported:<ul class="mycode_list"><li>Web server: LiteSpeed.<br />
</li>
<li>PHP version: 8.5.11.<br />
</li>
<li>PHP SAPI: <span style="font-weight: bold;" class="mycode_b">litespeed</span>.<br />
</li>
<li>Imagick available: <span style="font-weight: bold;" class="mycode_b">Yes</span>.<br />
</li>
<li>Opcode cache: Enabled.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=91" target="_blank" title="">ols-wp-server-branded-20261012.jpg</a> (Size: 109.41 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
This application-side result is stronger evidence of the active website runtime than a command-line PHP version alone. The opcode-cache statistics visible in the capture are a momentary lab snapshot, not a speed benchmark or a recommended target.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">If the results do not match</span><ul class="mycode_list"><li>Check the saved website engine and selected PHP version again.<br />
</li>
<li>Verify which binary and configuration file you inspected.<br />
</li>
<li>After an extension/configuration change, follow the appropriate service/PHP-worker reload process and recheck a fresh application request.<br />
</li>
<li>Check application errors before changing more settings; different runtimes can have different upload and memory limits as well as extensions.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Our verified result</span><br />
We identified separate aaPanel and lsphp installations, verified their loaded ini files and extension lists, and confirmed WordPress requests used litespeed SAPI. We did not use this guide to tune performance or change PHP limits.<br />
<br />
References: <a href="https://www.aapanel.com/docs/faq/multi-webserver_hosting.html" target="_blank" rel="noopener" class="mycode_url">aaPanel multi-webserver PHP management</a> and <a href="https://docs.openlitespeed.org/config/php/" target="_blank" rel="noopener" class="mycode_url">OpenLiteSpeed PHP documentation</a>. All screenshots are original AdminsForum lab captures.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
For OpenLiteSpeed, inspect <span style="font-weight: bold;" class="mycode_b">App Store → Installed → Openlitespeed → Setting → PHP Info</span>. Select the PHP version you intend to use. OpenLiteSpeed uses a separate lsphp installation, so an extension installed through the normal PHP-8.5 manager is not proof that lsphp has it.<br />
<br />
This guide was tested on our isolated aaPanel 8.0.6 / Ubuntu 22.04 lab on 12 October 2026. The OpenLiteSpeed manager reported version 1.8.5, and both PHP installations reported PHP 8.5.11. We also checked the actual WordPress runtime after switching that test site to Nginx + OpenLiteSpeed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Identify the website's engine and PHP version</span><br />
Open the website's configuration and check <span style="font-weight: bold;" class="mycode_b">Web Server</span> and <span style="font-weight: bold;" class="mycode_b">PHP version</span>. For our WP Toolkit site, those controls were under <span style="font-weight: bold;" class="mycode_b">WP Toolkit → Modify</span>. Do not assume that the server's default engine or a bare php command describes this particular website.<br />
<br />
If you still need to enable multiple services, see <a href="https://adminsforum.com/Thread-guide-enable-aapanel-multi-webserver-hosting-and-switch-a-website" target="_blank" rel="noopener" class="mycode_url">the tested multi-webserver installation guide</a>. Changing engines is a separate operation from checking PHP information.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Open the correct PHP manager</span><br />
In <span style="font-weight: bold;" class="mycode_b">App Store → Installed</span>, open the <span style="font-weight: bold;" class="mycode_b">Openlitespeed</span> row's Setting link, then choose <span style="font-weight: bold;" class="mycode_b">PHP Info</span>. We selected <span style="font-weight: bold;" class="mycode_b">PHP-85</span>. Wait for the data to finish loading: temporary empty cells or default No values are not a reliable result while the request is pending.<br />
<br />
The Basic Information section reported PHP 8.5.11 and the lsphp binary under /usr/local/lsws. Our initial capture is below.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=88" target="_blank" title="">ols-php-version-branded-20261012.jpg</a> (Size: 106.47 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Distinguish the two installations</span><br />
Our lab had:<ul class="mycode_list"><li>Normal aaPanel PHP binary: <br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php</code></div></div></li>
<li>OpenLiteSpeed PHP binary: <br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/bin/php</code></div></div></li>
</ul>
The matching 8.5.11 version numbers did not make these the same installation. Before we installed the lsphp Imagick extension, the normal aaPanel binary loaded Imagick while lsphp did not.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=89" target="_blank" title="">ols-php-compare-branded-20261012.jpg</a> (Size: 69.06 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
These comparison commands were run in CLI mode; the first label in the screenshot identifies the aaPanel PHP installation used with PHP-FPM, not an active FPM worker request. CLI settings and website settings can differ.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Verify the configuration file with the intended binary</span><br />
In the aaPanel Terminal, this read-only check prints the PHP version, loaded configuration file and selected extension availability:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/bin/php -r 'echo "PHP version: ".PHP_VERSION.PHP_EOL;echo "Loaded ini: ".php_ini_loaded_file().PHP_EOL;foreach(["exif","fileinfo","imagick","Zend OPcache"] as &#36;e)echo &#36;e.": ".(extension_loaded(&#36;e)?"loaded":"missing").PHP_EOL;'</code></div></div>Replace 85 with the version directory that actually exists on your server. Do not copy a path from another PHP version and do not create a public phpinfo.php file just to run this check.<br />
<br />
One detail mattered in our test: the panel displayed an ini path containing /php/85/litespeed/, while the lsphp binary reported the actual loaded path as:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/usr/local/lsws/lsphp85/etc/php/8.5/litespeed/php.ini</code></div></div>Check the loaded path before editing configuration. A path label in a panel is not a reason to create a second configuration file that the runtime never reads. We did not change a php.ini setting in this walkthrough.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Check the extensions required by your application</span><br />
Scroll through PHP Info and look at the database, image-processing and file-handling sections. WordPress needs its database connection and the image/file features used by your site. Install extensions for actual application requirements rather than enabling every optional item.<br />
<br />
After our lsphp setup, the panel showed EXIF, GD, ImageMagick and Fileinfo available. Imagick was installed during a separate tested setup step; this screenshot is the resulting configuration, not a promise that every fresh lsphp installation has it by default.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=90" target="_blank" title="">ols-extensions-branded-20261012.jpg</a> (Size: 112.67 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
To install a missing lsphp extension through aaPanel, use <span style="font-weight: bold;" class="mycode_b">Openlitespeed → Install extensions</span> for the selected version. Using the normal PHP-8.5 extension manager can affect the other installation instead.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Confirm what a real website request uses</span><br />
For WordPress, open <span style="font-weight: bold;" class="mycode_b">Tools → Site Health → Info → Server</span>. After the engine switch, our WordPress page reported:<ul class="mycode_list"><li>Web server: LiteSpeed.<br />
</li>
<li>PHP version: 8.5.11.<br />
</li>
<li>PHP SAPI: <span style="font-weight: bold;" class="mycode_b">litespeed</span>.<br />
</li>
<li>Imagick available: <span style="font-weight: bold;" class="mycode_b">Yes</span>.<br />
</li>
<li>Opcode cache: Enabled.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=91" target="_blank" title="">ols-wp-server-branded-20261012.jpg</a> (Size: 109.41 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
This application-side result is stronger evidence of the active website runtime than a command-line PHP version alone. The opcode-cache statistics visible in the capture are a momentary lab snapshot, not a speed benchmark or a recommended target.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">If the results do not match</span><ul class="mycode_list"><li>Check the saved website engine and selected PHP version again.<br />
</li>
<li>Verify which binary and configuration file you inspected.<br />
</li>
<li>After an extension/configuration change, follow the appropriate service/PHP-worker reload process and recheck a fresh application request.<br />
</li>
<li>Check application errors before changing more settings; different runtimes can have different upload and memory limits as well as extensions.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Our verified result</span><br />
We identified separate aaPanel and lsphp installations, verified their loaded ini files and extension lists, and confirmed WordPress requests used litespeed SAPI. We did not use this guide to tune performance or change PHP limits.<br />
<br />
References: <a href="https://www.aapanel.com/docs/faq/multi-webserver_hosting.html" target="_blank" rel="noopener" class="mycode_url">aaPanel multi-webserver PHP management</a> and <a href="https://docs.openlitespeed.org/config/php/" target="_blank" rel="noopener" class="mycode_url">OpenLiteSpeed PHP documentation</a>. All screenshots are original AdminsForum lab captures.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Check PHP OPcache in aaPanel: CLI vs PHP-FPM]]></title>
			<link>https://adminsforum.com/Thread-guide-check-php-opcache-in-aapanel-cli-vs-php-fpm</link>
			<pubDate>Tue, 13 Oct 2026 00:32:02 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-check-php-opcache-in-aapanel-cli-vs-php-fpm</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
An OPcache result from command-line PHP does not necessarily describe your website. Check the PHP version assigned to the site, confirm Zend OPcache is available, and inspect that version's PHP-FPM configuration separately. In our lab, CLI opcode caching was disabled while the PHP-FPM configuration reported it enabled.<br />
<br />
Tested on 12 October 2026 with aaPanel 8.0.6 and PHP 8.5.11. OPcache was already available; no extension installation or performance-setting change was needed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What OPcache does</span><br />
OPcache keeps compiled PHP bytecode so PHP does not need to parse and compile the same scripts on every request. It is separate from a full-page cache or a Redis-backed WordPress object cache. Finding OPcache does not prove those other caches are configured.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Check the PHP version your website uses</span><br />
Open the website's PHP version setting in aaPanel. For a WP Toolkit site, use <span style="font-weight: bold;" class="mycode_b">WP Toolkit → Modify → PHP version</span>. Our WordPress site uses PHP 8.5, so the commands below deliberately use the 85 installation directory.<br />
<br />
Open <span style="font-weight: bold;" class="mycode_b">App Store → Installed → PHP-8.5 → Setting → Service</span>. The panel shows the executable for that version:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php</code></div></div><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=77" target="_blank" title="">opcache-service-branded-20261012.jpg</a> (Size: 60.95 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
Do not rely on a bare php command unless you know which version it points to. A website using PHP 8.4 can have different extensions and settings from a PHP 8.5 command-line installation. Replace 85 with your actual aaPanel version directory when following this guide.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check extension availability in the PHP manager</span><br />
Click <span style="font-weight: bold;" class="mycode_b">phpinfo</span> in the same PHP manager. In our panel, the Basic Information section showed version 8.5.11 and the Buffer section showed <span style="font-weight: bold;" class="mycode_b">Zend OPcache → Yes</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=78" target="_blank" title="">opcache-phpinfo-branded-20261012.jpg</a> (Size: 132.3 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
This confirms availability in that PHP installation. It is not a measurement of cache hit rate on your live website. Our Install extensions list did not offer a separate OPcache Install row, so there was no reason to search for another package or reinstall PHP.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Compare CLI and PHP-FPM settings</span><br />
In the aaPanel Terminal, these read-only commands show selected configuration fields. They do not save settings or restart services. They use awk to filter the otherwise lengthy PHP information output.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Command-line PHP:</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -i | awk '/^(PHP Version =&gt;|Server API =&gt;|Loaded Configuration File =&gt;|Opcode Caching =&gt;|opcache.enable =&gt;|opcache.enable_cli =&gt;)/ {print}'</code></div></div>Look for Server API, Loaded Configuration File, Opcode Caching, opcache.enable and opcache.enable_cli.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">PHP-FPM configuration:</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -i | awk '/^(PHP Version =&gt;|Server API =&gt;|Loaded Configuration File =&gt;|Opcode Caching =&gt;|opcache.enable =&gt;|opcache.enable_cli =&gt;|opcache.memory_consumption =&gt;|opcache.validate_timestamps =&gt;|opcache.revalidate_freq =&gt;|opcache.max_accelerated_files =&gt;)/ {print}'</code></div></div>The php-fpm -i command inspects the FPM executable and its loaded configuration. It does not send a web request to your site's running worker pool. Per-pool overrides or application restrictions may still affect that site, so this is a configuration check rather than live traffic monitoring.<br />
<br />
Our results:<ul class="mycode_list"><li>CLI used <span style="font-weight: bold;" class="mycode_b">/www/server/php/85/etc/php-cli.ini</span>. Opcode Caching was Disabled, with opcache.enable_cli Off.<br />
</li>
<li>FPM used <span style="font-weight: bold;" class="mycode_b">/www/server/php/85/etc/php.ini</span>. Opcode Caching was Up and Running, with opcache.enable On.<br />
</li>
<li>The FPM settings reported 128 MB for OPcache memory, 10,000 maximum accelerated files, timestamp validation On and a 2-second revalidation interval.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=79" target="_blank" title="">opcache-runtime-branded-20261012.jpg</a> (Size: 124.85 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<br />
The screenshot uses an equivalent filtered read-only check; we also ran the exact command examples above. These numbers describe our lab, not a tuning prescription for every server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Interpret the result before changing anything</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Zend OPcache Yes, CLI caching Disabled:</span> this can be normal when opcache.enable_cli is Off. It does not by itself mean website caching is off.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">FPM configuration shows opcache.enable On:</span> OPcache is enabled in that configuration. Check the actual application through an authenticated monitoring method if you need hit-rate or memory-usage data.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Wrong PHP version or configuration file:</span> return to the site's PHP version setting and use the matching binary.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">OPcache unavailable:</span> inspect the extension/build options for your PHP version. Do not paste an opcache.so path copied from a different server or PHP version.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Why we did not increase the cache memory</span><br />
The lab already had OPcache enabled, and we had no workload evidence of a full cache. A larger memory allocation consumes server memory and is not automatically faster. Measure actual application workload before tuning.<br />
<br />
Keep timestamp validation appropriate to your deployment process. Turning it off without a reliable cache reset/reload process can leave old PHP code in use after an update. Do not copy old options such as opcache.fast_shutdown into modern PHP settings; PHP removed that directive in 7.2.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Do not leave a public phpinfo page behind</span><br />
The authenticated panel summary and filtered terminal checks were enough for this guide. We did not publish a phpinfo.php file or install a public cache dashboard. Detailed diagnostics can expose configuration information, so use an authenticated method for ongoing monitoring.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What was verified</span><br />
The panel reported Zend OPcache available, CLI and FPM loaded different configuration files, and the FPM configuration reported caching enabled. We did not benchmark speed, measure the live worker pool's hit rate or test disabling/re-enabling OPcache.<br />
<br />
References: <a href="https://www.php.net/manual/en/opcache.installation.php" target="_blank" rel="noopener" class="mycode_url">PHP OPcache installation</a> and <a href="https://www.php.net/manual/en/opcache.configuration.php" target="_blank" rel="noopener" class="mycode_url">PHP OPcache configuration</a>. Screenshots are original AdminsForum lab captures.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">Quick answer</span><br />
An OPcache result from command-line PHP does not necessarily describe your website. Check the PHP version assigned to the site, confirm Zend OPcache is available, and inspect that version's PHP-FPM configuration separately. In our lab, CLI opcode caching was disabled while the PHP-FPM configuration reported it enabled.<br />
<br />
Tested on 12 October 2026 with aaPanel 8.0.6 and PHP 8.5.11. OPcache was already available; no extension installation or performance-setting change was needed.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What OPcache does</span><br />
OPcache keeps compiled PHP bytecode so PHP does not need to parse and compile the same scripts on every request. It is separate from a full-page cache or a Redis-backed WordPress object cache. Finding OPcache does not prove those other caches are configured.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Check the PHP version your website uses</span><br />
Open the website's PHP version setting in aaPanel. For a WP Toolkit site, use <span style="font-weight: bold;" class="mycode_b">WP Toolkit → Modify → PHP version</span>. Our WordPress site uses PHP 8.5, so the commands below deliberately use the 85 installation directory.<br />
<br />
Open <span style="font-weight: bold;" class="mycode_b">App Store → Installed → PHP-8.5 → Setting → Service</span>. The panel shows the executable for that version:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php</code></div></div><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=77" target="_blank" title="">opcache-service-branded-20261012.jpg</a> (Size: 60.95 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
Do not rely on a bare php command unless you know which version it points to. A website using PHP 8.4 can have different extensions and settings from a PHP 8.5 command-line installation. Replace 85 with your actual aaPanel version directory when following this guide.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check extension availability in the PHP manager</span><br />
Click <span style="font-weight: bold;" class="mycode_b">phpinfo</span> in the same PHP manager. In our panel, the Basic Information section showed version 8.5.11 and the Buffer section showed <span style="font-weight: bold;" class="mycode_b">Zend OPcache → Yes</span>.<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=78" target="_blank" title="">opcache-phpinfo-branded-20261012.jpg</a> (Size: 132.3 KB / Downloads: 7)
<!-- end: postbit_attachments_attachment --><br />
<br />
This confirms availability in that PHP installation. It is not a measurement of cache hit rate on your live website. Our Install extensions list did not offer a separate OPcache Install row, so there was no reason to search for another package or reinstall PHP.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Compare CLI and PHP-FPM settings</span><br />
In the aaPanel Terminal, these read-only commands show selected configuration fields. They do not save settings or restart services. They use awk to filter the otherwise lengthy PHP information output.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Command-line PHP:</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -i | awk '/^(PHP Version =&gt;|Server API =&gt;|Loaded Configuration File =&gt;|Opcode Caching =&gt;|opcache.enable =&gt;|opcache.enable_cli =&gt;)/ {print}'</code></div></div>Look for Server API, Loaded Configuration File, Opcode Caching, opcache.enable and opcache.enable_cli.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">PHP-FPM configuration:</span><br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/sbin/php-fpm -i | awk '/^(PHP Version =&gt;|Server API =&gt;|Loaded Configuration File =&gt;|Opcode Caching =&gt;|opcache.enable =&gt;|opcache.enable_cli =&gt;|opcache.memory_consumption =&gt;|opcache.validate_timestamps =&gt;|opcache.revalidate_freq =&gt;|opcache.max_accelerated_files =&gt;)/ {print}'</code></div></div>The php-fpm -i command inspects the FPM executable and its loaded configuration. It does not send a web request to your site's running worker pool. Per-pool overrides or application restrictions may still affect that site, so this is a configuration check rather than live traffic monitoring.<br />
<br />
Our results:<ul class="mycode_list"><li>CLI used <span style="font-weight: bold;" class="mycode_b">/www/server/php/85/etc/php-cli.ini</span>. Opcode Caching was Disabled, with opcache.enable_cli Off.<br />
</li>
<li>FPM used <span style="font-weight: bold;" class="mycode_b">/www/server/php/85/etc/php.ini</span>. Opcode Caching was Up and Running, with opcache.enable On.<br />
</li>
<li>The FPM settings reported 128 MB for OPcache memory, 10,000 maximum accelerated files, timestamp validation On and a 2-second revalidation interval.<br />
</li>
</ul>
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=79" target="_blank" title="">opcache-runtime-branded-20261012.jpg</a> (Size: 124.85 KB / Downloads: 8)
<!-- end: postbit_attachments_attachment --><br />
<br />
The screenshot uses an equivalent filtered read-only check; we also ran the exact command examples above. These numbers describe our lab, not a tuning prescription for every server.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Interpret the result before changing anything</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Zend OPcache Yes, CLI caching Disabled:</span> this can be normal when opcache.enable_cli is Off. It does not by itself mean website caching is off.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">FPM configuration shows opcache.enable On:</span> OPcache is enabled in that configuration. Check the actual application through an authenticated monitoring method if you need hit-rate or memory-usage data.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Wrong PHP version or configuration file:</span> return to the site's PHP version setting and use the matching binary.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">OPcache unavailable:</span> inspect the extension/build options for your PHP version. Do not paste an opcache.so path copied from a different server or PHP version.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Why we did not increase the cache memory</span><br />
The lab already had OPcache enabled, and we had no workload evidence of a full cache. A larger memory allocation consumes server memory and is not automatically faster. Measure actual application workload before tuning.<br />
<br />
Keep timestamp validation appropriate to your deployment process. Turning it off without a reliable cache reset/reload process can leave old PHP code in use after an update. Do not copy old options such as opcache.fast_shutdown into modern PHP settings; PHP removed that directive in 7.2.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Do not leave a public phpinfo page behind</span><br />
The authenticated panel summary and filtered terminal checks were enough for this guide. We did not publish a phpinfo.php file or install a public cache dashboard. Detailed diagnostics can expose configuration information, so use an authenticated method for ongoing monitoring.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">What was verified</span><br />
The panel reported Zend OPcache available, CLI and FPM loaded different configuration files, and the FPM configuration reported caching enabled. We did not benchmark speed, measure the live worker pool's hit rate or test disabling/re-enabling OPcache.<br />
<br />
References: <a href="https://www.php.net/manual/en/opcache.installation.php" target="_blank" rel="noopener" class="mycode_url">PHP OPcache installation</a> and <a href="https://www.php.net/manual/en/opcache.configuration.php" target="_blank" rel="noopener" class="mycode_url">PHP OPcache configuration</a>. Screenshots are original AdminsForum lab captures.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Install PHP Imagick in aaPanel and Verify WordPress Detects It]]></title>
			<link>https://adminsforum.com/Thread-guide-install-php-imagick-in-aapanel-and-verify-wordpress-detects-it</link>
			<pubDate>Mon, 12 Oct 2026 23:33:15 +0800</pubDate>
			<dc:creator><![CDATA[<a href="https://adminsforum.com/member.php?action=profile&uid=2">DEV</a>]]></dc:creator>
			<guid isPermaLink="false">https://adminsforum.com/Thread-guide-install-php-imagick-in-aapanel-and-verify-wordpress-detects-it</guid>
			<description><![CDATA[<span style="font-weight: bold;" class="mycode_b">How do you install Imagick for WordPress on aaPanel?</span><br />
Confirm the PHP version used by your website. In aaPanel’s App Store, open that PHP version’s Setting → Install extensions and install the row named imagemagick. Wait for compilation to complete, then verify WordPress Site Health → Info → Server reports the Imagick library as available.<br />
<br />
We tested this on aaPanel 8.0.6 Free Edition with PHP 8.5.11 and WordPress 7.1.3. The panel installed Imagick 3.8.1. WordPress detected it, and a separate command-line test created a 64 × 64 image, resized it to 32 × 32 and encoded a PNG successfully.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Imagick and ImageMagick are related but different names</span><br />
ImageMagick is the underlying image-processing library/toolset. Imagick is the PHP extension that exposes its functionality to PHP applications. Our aaPanel extension row was named <span style="font-weight: bold;" class="mycode_b">imagemagick</span>, while WordPress referred to the missing PHP module as <span style="font-weight: bold;" class="mycode_b">imagick</span>. Installing the operating system’s command-line image tool alone is not proof that the website’s PHP runtime has its extension loaded.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the WordPress warning</span><br />
Open WordPress → Tools → Site Health, let the checks finish and expand the missing-module recommendation. After our earlier EXIF installation, the remaining optional-module warning named imagick.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=69" target="_blank" title="">imagick-wordpress-before-20261012.jpg</a> (Size: 142.29 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The remaining Imagick warning before installation.</span><br />
<br />
Optional-module advice is different from a fatal website error. Install the extension for a clear requirement and verify it afterward; do not assume every warning needs a broad server reconfiguration.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the website’s PHP version</span><br />
Use Site Health → Info → Server to read the actual PHP version, or verify the site’s PHP selection in aaPanel. Our site used PHP 8.5.11. The server also had PHP 8.4, so we deliberately selected the 8.5 manager.<br />
<br />
Take a current backup and choose an appropriate maintenance period on a live server. A PHP extension installation may reload or restart that PHP version’s service and affect other sites using it.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Install the matching extension</span><br />
In aaPanel select <span style="font-weight: bold;" class="mycode_b">App Store → Installed</span>. Find <span style="font-weight: bold;" class="mycode_b">PHP-8.5</span> for this example and choose <span style="font-weight: bold;" class="mycode_b">Setting</span>. Open <span style="font-weight: bold;" class="mycode_b">Install extensions</span>.<br />
<br />
Locate <span style="font-weight: bold;" class="mycode_b">imagemagick</span>, described in our list as <span style="font-weight: bold;" class="mycode_b">Imagick High Performance Graphics Library</span>. Click Install in that row and confirm Install【imagemagick】 after checking the PHP version and extension name.<br />
<br />
The row displayed Installing while the job ran. Compilation takes time; do not submit duplicate installs or judge success from a pending status. Read the installation task/log if it fails or stops progressing.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Confirm the installed state</span><br />
After the job finished, we reopened the PHP manager and extension list. The imagemagick row offered <span style="font-weight: bold;" class="mycode_b">Uninstall</span>, showing that the installed module was recognised by the panel.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=70" target="_blank" title="">imagick-manager-after-20261012.jpg</a> (Size: 269.33 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The refreshed PHP 8.5 extension list after installation.</span><br />
<br />
If a refresh briefly leaves the table blank, reopen the manager after the task has completed. Do not treat an empty table as proof of either success or failure.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Verify WordPress uses it</span><br />
Return to WordPress Site Health and let the checks complete. In our test, the missing-module recommendation disappeared. We then opened <span style="font-weight: bold;" class="mycode_b">Info → Server</span> and checked <span style="font-weight: bold;" class="mycode_b">Is the Imagick library available?</span>. It reported <span style="font-weight: bold;" class="mycode_b">Yes</span>.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=71" target="_blank" title="">imagick-runtime-info-20261012.jpg</a> (Size: 160.77 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">WordPress’s own runtime reports that Imagick is available on PHP 8.5.11.</span><br />
<br />
A command-line check alone is not enough if CLI and the website use different PHP configurations. WordPress’s result confirms availability to the website. Our remaining recommendations concerned inactive plugins/themes; this installation does not claim to fix unrelated maintenance findings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify a basic image operation</span><br />
We also ran a small private command-line test with the exact aaPanel PHP binary. It reported EXIF loaded, Imagick loaded and extension version 3.8.1. It created and resized a test image, then produced a non-empty PNG blob.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=72" target="_blank" title="">imagick-functional-test-20261012.jpg</a> (Size: 178.42 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Our functional test returned 32 × 32 pixels and 160 PNG bytes.</span><br />
<br />
For administrators who want a basic version-specific availability check:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -r 'echo extension_loaded("imagick") ? "Imagick loaded
" : "Imagick missing
";'</code></div></div>Use the correct path for your installed PHP version. The test was performed privately in the terminal; we did not leave a public phpinfo or diagnostic script on the website.<br />
<br />
A small PNG test does not prove that every image type, large upload, PDF delegate or animation workflow works. Verify the formats and operations your application actually needs.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Installed in panel but WordPress still says missing:</span> compare the website’s selected PHP version and loaded configuration with the version you changed.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Compilation fails:</span> inspect the actual build error, dependencies, memory/disk availability and source connectivity before retrying.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Imagick loads but a format fails:</span> review support and policy for that specific operation. Do not broadly disable ImageMagick security policies just to suppress an error.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">WordPress image upload still fails:</span> check the upload limit, file type, permissions and exact application error. Imagick availability does not resolve every media problem.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Verified outcome</span><br />
The panel recognised imagemagick as installed, WordPress reported Imagick available and the private image resize/PNG test passed. EXIF stayed loaded. No other PHP version was changed, and no public diagnostic endpoint was created.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References:</span> <a href="https://www.php.net/manual/en/book.imagick.php" target="_blank" rel="noopener" class="mycode_url">PHP Imagick manual</a>, <a href="https://adminsforum.com/Thread-guide-install-php-exif-in-aapanel-and-fix-the-wordpress-warning" target="_blank" rel="noopener" class="mycode_url">our EXIF guide</a> and <a href="https://adminsforum.com/Thread-guide-check-wordpress-site-health-on-an-aapanel-website" target="_blank" rel="noopener" class="mycode_url">our Site Health guide</a>. Screenshots and tests are from the AdminsForum lab.]]></description>
			<content:encoded><![CDATA[<span style="font-weight: bold;" class="mycode_b">How do you install Imagick for WordPress on aaPanel?</span><br />
Confirm the PHP version used by your website. In aaPanel’s App Store, open that PHP version’s Setting → Install extensions and install the row named imagemagick. Wait for compilation to complete, then verify WordPress Site Health → Info → Server reports the Imagick library as available.<br />
<br />
We tested this on aaPanel 8.0.6 Free Edition with PHP 8.5.11 and WordPress 7.1.3. The panel installed Imagick 3.8.1. WordPress detected it, and a separate command-line test created a 64 × 64 image, resized it to 32 × 32 and encoded a PNG successfully.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Imagick and ImageMagick are related but different names</span><br />
ImageMagick is the underlying image-processing library/toolset. Imagick is the PHP extension that exposes its functionality to PHP applications. Our aaPanel extension row was named <span style="font-weight: bold;" class="mycode_b">imagemagick</span>, while WordPress referred to the missing PHP module as <span style="font-weight: bold;" class="mycode_b">imagick</span>. Installing the operating system’s command-line image tool alone is not proof that the website’s PHP runtime has its extension loaded.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">1. Confirm the WordPress warning</span><br />
Open WordPress → Tools → Site Health, let the checks finish and expand the missing-module recommendation. After our earlier EXIF installation, the remaining optional-module warning named imagick.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=69" target="_blank" title="">imagick-wordpress-before-20261012.jpg</a> (Size: 142.29 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The remaining Imagick warning before installation.</span><br />
<br />
Optional-module advice is different from a fatal website error. Install the extension for a clear requirement and verify it afterward; do not assume every warning needs a broad server reconfiguration.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">2. Check the website’s PHP version</span><br />
Use Site Health → Info → Server to read the actual PHP version, or verify the site’s PHP selection in aaPanel. Our site used PHP 8.5.11. The server also had PHP 8.4, so we deliberately selected the 8.5 manager.<br />
<br />
Take a current backup and choose an appropriate maintenance period on a live server. A PHP extension installation may reload or restart that PHP version’s service and affect other sites using it.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">3. Install the matching extension</span><br />
In aaPanel select <span style="font-weight: bold;" class="mycode_b">App Store → Installed</span>. Find <span style="font-weight: bold;" class="mycode_b">PHP-8.5</span> for this example and choose <span style="font-weight: bold;" class="mycode_b">Setting</span>. Open <span style="font-weight: bold;" class="mycode_b">Install extensions</span>.<br />
<br />
Locate <span style="font-weight: bold;" class="mycode_b">imagemagick</span>, described in our list as <span style="font-weight: bold;" class="mycode_b">Imagick High Performance Graphics Library</span>. Click Install in that row and confirm Install【imagemagick】 after checking the PHP version and extension name.<br />
<br />
The row displayed Installing while the job ran. Compilation takes time; do not submit duplicate installs or judge success from a pending status. Read the installation task/log if it fails or stops progressing.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">4. Confirm the installed state</span><br />
After the job finished, we reopened the PHP manager and extension list. The imagemagick row offered <span style="font-weight: bold;" class="mycode_b">Uninstall</span>, showing that the installed module was recognised by the panel.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=70" target="_blank" title="">imagick-manager-after-20261012.jpg</a> (Size: 269.33 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">The refreshed PHP 8.5 extension list after installation.</span><br />
<br />
If a refresh briefly leaves the table blank, reopen the manager after the task has completed. Do not treat an empty table as proof of either success or failure.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">5. Verify WordPress uses it</span><br />
Return to WordPress Site Health and let the checks complete. In our test, the missing-module recommendation disappeared. We then opened <span style="font-weight: bold;" class="mycode_b">Info → Server</span> and checked <span style="font-weight: bold;" class="mycode_b">Is the Imagick library available?</span>. It reported <span style="font-weight: bold;" class="mycode_b">Yes</span>.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=71" target="_blank" title="">imagick-runtime-info-20261012.jpg</a> (Size: 160.77 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">WordPress’s own runtime reports that Imagick is available on PHP 8.5.11.</span><br />
<br />
A command-line check alone is not enough if CLI and the website use different PHP configurations. WordPress’s result confirms availability to the website. Our remaining recommendations concerned inactive plugins/themes; this installation does not claim to fix unrelated maintenance findings.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">6. Verify a basic image operation</span><br />
We also ran a small private command-line test with the exact aaPanel PHP binary. It reported EXIF loaded, Imagick loaded and extension version 3.8.1. It created and resized a test image, then produced a non-empty PNG blob.<br />
<br />
<!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://adminsforum.com/images/attachtypes/image.png" title="JPG Image" border="0" alt=".jpg" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=72" target="_blank" title="">imagick-functional-test-20261012.jpg</a> (Size: 178.42 KB / Downloads: 10)
<!-- end: postbit_attachments_attachment --><br />
<span style="font-style: italic;" class="mycode_i">Our functional test returned 32 × 32 pixels and 160 PNG bytes.</span><br />
<br />
For administrators who want a basic version-specific availability check:<br />
<div class="codeblock"><div class="title af-code-title"><span>Code:</span><button type="button" class="af-code-copy" aria-label="Copy code" title="Copy code"><i class="far fa-copy" aria-hidden="true"></i><span>Copy</span></button><span class="af-code-status" role="status" aria-live="polite"></span></div><div class="body" dir="ltr"><code>/www/server/php/85/bin/php -r 'echo extension_loaded("imagick") ? "Imagick loaded
" : "Imagick missing
";'</code></div></div>Use the correct path for your installed PHP version. The test was performed privately in the terminal; we did not leave a public phpinfo or diagnostic script on the website.<br />
<br />
A small PNG test does not prove that every image type, large upload, PDF delegate or animation workflow works. Verify the formats and operations your application actually needs.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">Troubleshooting</span><ul class="mycode_list"><li><span style="font-weight: bold;" class="mycode_b">Installed in panel but WordPress still says missing:</span> compare the website’s selected PHP version and loaded configuration with the version you changed.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Compilation fails:</span> inspect the actual build error, dependencies, memory/disk availability and source connectivity before retrying.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">Imagick loads but a format fails:</span> review support and policy for that specific operation. Do not broadly disable ImageMagick security policies just to suppress an error.<br />
</li>
<li><span style="font-weight: bold;" class="mycode_b">WordPress image upload still fails:</span> check the upload limit, file type, permissions and exact application error. Imagick availability does not resolve every media problem.<br />
</li>
</ul>
<br />
<span style="font-weight: bold;" class="mycode_b">Verified outcome</span><br />
The panel recognised imagemagick as installed, WordPress reported Imagick available and the private image resize/PNG test passed. EXIF stayed loaded. No other PHP version was changed, and no public diagnostic endpoint was created.<br />
<br />
<span style="font-weight: bold;" class="mycode_b">References:</span> <a href="https://www.php.net/manual/en/book.imagick.php" target="_blank" rel="noopener" class="mycode_url">PHP Imagick manual</a>, <a href="https://adminsforum.com/Thread-guide-install-php-exif-in-aapanel-and-fix-the-wordpress-warning" target="_blank" rel="noopener" class="mycode_url">our EXIF guide</a> and <a href="https://adminsforum.com/Thread-guide-check-wordpress-site-health-on-an-aapanel-website" target="_blank" rel="noopener" class="mycode_url">our Site Health guide</a>. Screenshots and tests are from the AdminsForum lab.]]></content:encoded>
		</item>
	</channel>
</rss>