PHP

PHP7.4升级8.3后wordpress博客遇到的问题

博主的wordpress一直都跟随官方推送的更新,一般只要提示了就会点更新,这么多年也从来没有出现更挂了的情况,但是最近更新后,管理后台赫然弹出了PHP7.4已过期的,最低满足要求版本为PHP8.3的警告提示,于是强迫症发作,升级了一波,果然升级后访问页面直接出现了PHP崩溃的情况,特此记录下一些处理方法。

首先,既然官方提示了升级警告,那自然表明wordpress本身代码是都可以兼容8.3版本的PHP的,问题基本都出在各种常年没人维护的插件上,首先第一个:

[Fri Jul 11 16:20:57.973316 2025] [proxy_fcgi:error] [pid 19955:tid 20046] [client 85.208.96.204:23228] AH01071: Got error 'PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function create_function() in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php:189\nStack trace:\n#0 /var/www/vhosts/blog.k-res.net/wp-settings.php(545): include_once()\n#1 /var/www/vhosts/blog.k-res.net/wp-config.php(73): require_once('...')\n#2 /var/www/vhosts/blog.k-res.net/wp-load.php(50): require_once('...')\n#3 /var/www/vhosts/blog.k-res.net/wp-blog-header.php(13): require_once('...')\n#4 /var/www/vhosts/blog.k-res.net/index.php(17): require('...')\n#5 {main}\n  thrown in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php on line 189'
[Fri Jul 11 16:21:22.922529 2025] [proxy_fcgi:error] [pid 19956:tid 20045] [client 66.249.68.38:61524] AH01071: Got error 'PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function create_function() in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php:189\nStack trace:\n#0 /var/www/vhosts/blog.k-res.net/wp-settings.php(545): include_once()\n#1 /var/www/vhosts/blog.k-res.net/wp-config.php(73): require_once('...')\n#2 /var/www/vhosts/blog.k-res.net/wp-load.php(50): require_once('...')\n#3 /var/www/vhosts/blog.k-res.net/wp-blog-header.php(13): require_once('...')\n#4 /var/www/vhosts/blog.k-res.net/index.php(17): require('...')\n#5 {main}\n  thrown in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php on line 189'
[Fri Jul 11 16:21:52.750113 2025] [proxy_fcgi:error] [pid 19955:tid 20013] [client 49.232.55.15:43176] AH01071: Got error 'PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function create_function() in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php:189\nStack trace:\n#0 /var/www/vhosts/blog.k-res.net/wp-settings.php(545): include_once()\n#1 /var/www/vhosts/blog.k-res.net/wp-config.php(73): require_once('...')\n#2 /var/www/vhosts/blog.k-res.net/wp-load.php(50): require_once('...')\n#3 /var/www/vhosts/blog.k-res.net/wp-blog-header.php(13): require_once('...')\n#4 /var/www/vhosts/blog.k-res.net/index.php(17): require('...')\n#5 {main}\n  thrown in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php on line 189'
[Fri Jul 11 16:21:52.750983 2025] [proxy_fcgi:error] [pid 19956:tid 20010] [client 49.232.55.15:43192] AH01071: Got error 'PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function create_function() in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php:189\nStack trace:\n#0 /var/www/vhosts/blog.k-res.net/wp-settings.php(545): include_once()\n#1 /var/www/vhosts/blog.k-res.net/wp-config.php(73): require_once('...')\n#2 /var/www/vhosts/blog.k-res.net/wp-load.php(50): require_once('...')\n#3 /var/www/vhosts/blog.k-res.net/wp-blog-header.php(13): require_once('...')\n#4 /var/www/vhosts/blog.k-res.net/index.php(17): require('...')\n#5 {main}\n  thrown in /var/www/vhosts/blog.k-res.net/wp-content/plugins/custom-iframe-widget/custom-iframe-widget.php on line 189'

简单看了下调用栈,发现果然是某个“古早”插件:“custom-iframe-widget”的问题,查了下报错异常“Call to undefined function create_function()”,就是8.3中废弃的函数,要换成匿名函数实现,于是小改了一下:

181 function custom_parse_iframe_widget($text)
182 {
183         return preg_replace_callback("@(?:<p>\s*)?\[ShaktiIFrame\s*(.*?)\](?:\s*</p>)?@", 'shakti_iframe_replace', $text);
184 }
185 
186 add_filter('the_content', 'custom_parse_iframe_widget');
187 add_filter('the_excerpt', 'custom_parse_iframe_widget');
188  $new_func = function() {register_widget("Custom_IFrame_Widget");};
189 //add_action( 'widgets_init', create_function( '', 'register_widget("Custom_IFrame_Widget");' ) );
190 add_action( 'widgets_init', $new_func );
191 ?>

结果,又报了新的错误:

Continue reading…

隐藏http返回消息头中的Apache及PHP信息

搬家之后注意到的一个小细节,之前用lighttpd时没太在意这个细节,今天发现了博客http返回头里有些不必要的信息,比如:

Server: Apache 2.4.XXX OpenSSL XXX
X-Powered-By: PHP/X.X.XX

顺手查了下隐藏掉的方法:

首先是Apache的,修改配置文件 /etc/httpd/conf/httpd.conf,加入

ServerTokens Prod
ServerSignature Off

重启httpd服务即可,接下来是PHP,修改配置文件/etc/php.ini,找到
Continue reading…

内网Visual Studio Code通过XDebug远程调试linux服务器PHP脚本

开发环境是这样:一台位于内网环境下的Windows机器使用VSCode作为IDE编写PHP脚本项目,一台位于公网的linux服务器运行lighttpd、fastcgi PHP用于部署调试。开发机所在网络环境不允许或不方便进行端口映射来打开XDebug所需的本地调试监听端口(默认9000),同时也不想安装本机PHP服务器来调试,于是采用本机编写PHP,然后上传linux服务器直接远程调试,记录环境搭建过程如下:
首先配置好开发机的IDE环境,我用的是VSCode 1.6.1,然后安装PHP Debug扩展,完成后选择一个指定文件夹作为项目根目录并在调试页中新建PHP调试配置,这时会在项目文件夹中生成.vscode/launch.json配置文件,按照PHP Debug的说明,加入serverSourceRoot与localSourceRoot,参考如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "serverSourceRoot": "/var/www/lighttpd/phpproj",
            "localSourceRoot": "${workspaceRoot}"
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000,
            "serverSourceRoot": "/var/www/lighttpd/phpproj",
            "localSourceRoot": "${workspaceRoot}"
        }
    ]
}

其中serverSourceRoot为项目位于服务器端的存储位置完整路径,localSourceRoot为本地项目存储位置完整路径,一般用环境变量${workspaceRoot}即可表示项目根目录。
Continue reading…