WordPress+BuddyPress注册页面404问题的解决
欢迎转载!转载时请注明出处:http://blog.csdn.net/nfer_zhuang/article/details/50316171
前言
WordPress自带的注册页面比较简陋,BuddyPress插件提供了一个比较丰富的注册页面,但是当我打开页面时却显示了“404 Not Found”(已打开WordPress的注册开关并设置了Buddypress的注册页面),本篇文章就是记录如何排查和解决该问题的。
问题截图
注:我是在WordPress4.3.1版本下进行的测试
排查问题
确认BuddyPress页面设置
通过截图,我们确认设置了使用BuddyPress的注册页面来替换原生页面。
确认页面是否可以直接打开
我们注意在每个设置的右边有一个view的按钮,那么直接点击这个按钮是否可以打开页面呢?
通过截图,我们确认直接打开页面是OK的,至少说明设置是有效的,且页面存在。
但是,我们发现了一个奇怪的地方,就是这两个页面的URL中都带有一个index.php
,这是个什么东西呢?看上去完全不符合常理啊。
固定链接
通过查询资料,我们发现这个index.php
是根据固定链接中的设置添加到URL中的。
那为什么WordPress会设置成/index.php/*
这种反人类的方式呢?
源码分析
在wp-admin/includes/upgrade.php文件下有下述代码:
/** The Permalink structures to attempt.** The first is designed for mod_rewrite or nginx rewriting.** The second is PATHINFO-based permalinks for web server configurations* without a true rewrite module enabled.*/$permalink_structures = array('/%year%/%monthnum%/%day%/%postname%/','/index.php/%year%/%monthnum%/%day%/%postname%/');foreach ( (array) $permalink_structures as $permalink_structure ) {$wp_rewrite->set_permalink_structure( $permalink_structure );/** Flush rules with the hard option to force refresh of the web-server's* rewrite config file (e.g. .htaccess or web.config).*/$wp_rewrite->flush_rules( true );// Test against a real WordPress Post, or if none were created, a random 404 page.$test_url = get_permalink( 1 );if ( ! $test_url ) {$test_url = home_url( '/wordpress-check-for-rewrites/' );}/** Send a request to the site, and check whether* the 'x-pingback' header is returned as expected.** Uses wp_remote_get() instead of wp_remote_head() because web servers* can block head requests.*/$response = wp_remote_get( $test_url, array( 'timeout' => 5 ) );$x_pingback_header = wp_remote_retrieve_header( $response, 'x-pingback' );$pretty_permalinks = $x_pingback_header && $x_pingback_header === get_bloginfo( 'pingback_url' );if ( $pretty_permalinks ) {return true;}}
上述代码是在用户安装WordPress时候运行的代码片段,通过添加打印,我们确认上面的foreach
loop在运行到'/index.php/%year%/%monthnum%/%day%/%postname%/'
的时候才返回true。
回到上面permalink_structures数组的注释上:
/** The Permalink structures to attempt.** The first is designed for mod_rewrite or nginx rewriting.** The second is PATHINFO-based permalinks for web server configurations* without a true rewrite module enabled.*/
我们了解到第一个固定链接格式是针对于支持mod_rewrite
或nginx rewriting
的,而第二个则是针对不支持rewrite
的HTTP Server环境的。
我这里使用的是LAMP的环境,理论上是支持rewrite
的,那么下一步我们就开始排查rewrite
功能。
LAMP的rewrite功能
检查apache是否已经配置rewrite功能
通过搜索,确认在apache2中已经配置了rewrite功能
$ grep rewrite ./ -nR
./mods-available/rewrite.load:1:LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
./mods-enabled/rewrite.load:1:LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
$ ls /usr/lib/apache2/modules/mod_rewrite.so
/usr/lib/apache2/modules/mod_rewrite.so
我们发现在mods-enabled中已经包含rewrite.load,且mod_rewrite.so文件存在。
通过PHP检查rewrite功能是否已配置
stackoverflow中有一个回答中给出了一种方法:
in_array('mod_rewrite', apache_get_modules());
我们添加了一些打印信息:
<?php
if (in_array('mod_rewrite', apache_get_modules()))print "The apache module mod_rewrite is enabled.<br/>\n";
elseprint "The apache module mod_rewrite is NOT enabled.<br/>\n";
但是在cli下运行报错:
$ php apache_rewrite_check
PHP Fatal error: Call to undefined function apache_get_modules() in /home/nfer/bak/apache_rewrite_check on line 2
我们尝试在浏览器中访问该文件,发现可以运行,且输出了The apache module mod_rewrite is enabled.
信息,证明在apache运行环境下通过PHP确认是支持rewrite
功能的。
通过shell命令行检查rewrite功能是否已配置
同样,在该篇回答中给出了一种在Ubuntu命令行下检查是否打开了rewrite
功能的方法:
$ apachectl -M | grep rewriterewrite_module (shared)
通过PHP实际测试rewrite功能
按照stackoverflow给出的例子,我们创建了rewrite文件夹,并在该文件夹下创建了.htaccess和index.php文件,内容分别为:
$ cat .htaccess
RewriteEngine On
RewriteRule ^inc/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
$ cat index.php
<?php
print "hello world.<br/>\n";
我们测试,通过http://localhost/rewrite/ 或 http://localhost/rewrite/123123 或 http://localhost/rewrite/hello 以及任何http://localhost/rewrite/ 前缀的地址都能正确输出hello world.
,即PHP的rewrite功能是OK的。
WordPress的rewrite判断
我们重点来看一下foreach
的处理:
$wp_rewrite->set_permalink_structure( $permalink_structure );/** Flush rules with the hard option to force refresh of the web-server's* rewrite config file (e.g. .htaccess or web.config).*/$wp_rewrite->flush_rules( true );// Test against a real WordPress Post, or if none were created, a random 404 page.$test_url = get_permalink( 1 );if ( ! $test_url ) {$test_url = home_url( '/wordpress-check-for-rewrites/' );}/** Send a request to the site, and check whether* the 'x-pingback' header is returned as expected.** Uses wp_remote_get() instead of wp_remote_head() because web servers* can block head requests.*/$response = wp_remote_get( $test_url, array( 'timeout' => 5 ) );$x_pingback_header = wp_remote_retrieve_header( $response, 'x-pingback' );$pretty_permalinks = $x_pingback_header && $x_pingback_header === get_bloginfo( 'pingback_url' );if ( $pretty_permalinks ) {return true;}
上面的测试主要包括以下几个步骤:
1. 设置固定链接格式
2. 将rewrite规则写入到文件中
3. 使用第一篇博客(id为1)来实际测试rewrite效果
4. 发送wp_remote_get请求并检测返回的header中是否包含x-pingback字段(URL可以访问的话,response中会包含x-pingback字段,否则不包含该字段)
注:更多关于x-pingback的资料请移步WordPress官方文档
flush_rules()
在上面的代码中有一处代码如下:
/** Flush rules with the hard option to force refresh of the web-server's* rewrite config file (e.g. .htaccess or web.config).*/$wp_rewrite->flush_rules( true );
继续看flush_rules函数的实现:
public function flush_rules( $hard = true ) {static $do_hard_later = null;// Prevent this action from running before everyone has registered their rewrites.if ( ! did_action( 'wp_loaded' ) ) {add_action( 'wp_loaded', array( $this, 'flush_rules' ) );$do_hard_later = ( isset( $do_hard_later ) ) ? $do_hard_later || $hard : $hard;return;}if ( isset( $do_hard_later ) ) {$hard = $do_hard_later;unset( $do_hard_later );}delete_option('rewrite_rules');$this->wp_rewrite_rules();/*** Filter whether a "hard" rewrite rule flush should be performed when requested.** A "hard" flush updates .htaccess (Apache) or web.config (IIS).** @since 3.7.0** @param bool $hard Whether to flush rewrite rules "hard". Default true.*/if ( ! $hard || ! apply_filters( 'flush_rewrite_rules_hard', true ) ) {return;}if ( function_exists( 'save_mod_rewrite_rules' ) )save_mod_rewrite_rules();if ( function_exists( 'iis7_save_url_rewrite_rules' ) )iis7_save_url_rewrite_rules();}
该函数包括以下流程:
1. 处理在wp_loaded之前的flush_rules请求
2. 更新rewrite_rules配置(到数据库中)
3. 更加环境不同,分别调用save_mod_rewrite_rules和iis7_save_url_rewrite_rules来写入rewrite规则到文件系统中
save_mod_rewrite_rules()
因为我使用的LAMP环境,因此在flush_rules()中实际作用的是save_mod_rewrite_rules()函数,实现如下:
function save_mod_rewrite_rules() {if ( is_multisite() )return;global $wp_rewrite;$home_path = get_home_path();$htaccess_file = $home_path.'.htaccess';/** If the file doesn't already exist check for write access to the directory* and whether we have some rules. Else check for write access to the file.*/if ((!file_exists($htaccess_file) && is_writable($home_path) && $wp_rewrite->using_mod_rewrite_permalinks()) || is_writable($htaccess_file)) {if ( got_mod_rewrite() ) {$rules = explode( "\n", $wp_rewrite->mod_rewrite_rules() );return insert_with_markers( $htaccess_file, 'WordPress', $rules );}}return false;
}
在上述代码中,有几处条件检查:
1. 判断htaccess_file文件是否不存在
2. 判断home_path目录是否可写
3. 判断htaccess_file文件是否可写
其实,看到这里我们需要检查是否在安装WordPress的时候WordPress程序不具有home_path目录和htaccess_file文件的写权限?
通过ls -l可以得到下述的列表:
/var/www/tag/WordPress_4_3_1$ ls -l ../
total 4
drwxrwxr-x 6 nfer nfer 4096 12月 15 17:38 WordPress_4_3_1
其中WordPress_4_3_1目录的读写权限是775,即当前用户和当前组均具有读写执行权限,其它用户只有读和执行权限并没有写入权限。我们再看一下apache进行的用户名:
/var/www/tag/WordPress_4_3_1$ ps auxf | grep apache
root 1071 0.0 0.2 38048 9024 ? Ss 04:15 0:08 /usr/sbin/apache2 -k start
www-data 4695 0.0 1.0 73968 44636 ? S 09:04 0:11 \_ /usr/sbin/apache2 -k start
www-data 4723 0.0 1.1 76304 46396 ? S 09:14 0:10 \_ /usr/sbin/apache2 -k start
可以看到apache是通过root用户启动的,然后每个工作进程是使用www-data用户启动的。
修改文件拥有者并重新安装WordPress
通过下述命令,修改WordPress目录的拥有者为www-data:
/var/www/tag$ sudo chown www-data WordPress_4_3_1/ -R
[sudo] password for nfer:
/var/www/tag$ ls -l
total 4
drwxrwxr-x 6 www-data nfer 4096 12月 15 17:38 WordPress_4_3_1
删除并重新创建数据库,删除wp-config.php文件,重新打开WordPress安装程序,整个流程完成后,我们再打开”设置-固定链接”页面,发现固定链接格式为'/%year%/%monthnum%/%day%/%postname%/'
:
总结
该文章描述了我从最开始遇到WordPress+BuddyPress无法打开注册页面问题,到一步步的通过查询资料、阅读相关源码,并最终解决问题的过程。在实际解决问题的过程中,有一些地方并没有详细展开,一些遗留问题已附在下面。
解决问题后,再次打开注册页面,效果如下:
遗留问题
- 为什么在.htaccess无法写入的情况下,使用
'/index.php/%year%/%monthnum%/%day%/%postname%/'
rewrite规则? '/index.php/%year%/%monthnum%/%day%/%postname%/'
是如何在.htaccess无法工作的情况下产生实际效果的?- flush_rules函数中的wp_loaded逻辑是否有必要?
WordPress+BuddyPress注册页面404问题的解决相关推荐
- gii无法访问 yii2_YII2框架访问gii、debug页面404的错误解决方法
之前在介绍Yii框架的时候就说过 Yii 支持 gii 功能, gii 去自动生成 Web 站点常用功能的代码,也就是我们经常说的 CURD 操作,增删改查.使用 gii 生成代码也是非常的简单,Gi ...
- Tomcat容器部署 浏览器访问服务器页面404 403错误 解决方法
启动一个tomcat容器,注意:新版本tomcat镜像启动时必须映射端口(8080为默认容器端口) docker run -d --name tomcat -p 8080:8080 -v /mnt/e ...
- WordPress更改“固定链接”后 页面404原因及解决方法(Nginx版)
网上盛传的方法是: 在 /etc/nginx/nginx.conf文件的 loction / {} 中添加 if (-f $request_filename/index.html){rewrite ( ...
- WordPress前台后台页面打开慢的解决方法
写个人网站用WordPress程序是一个不错的选择,但是目前安装之后速度很慢,后台配置页面半天打不开,在网上查了一下原来是Google被墙导致,WordPress默认模板会加载谷歌的open-sans ...
- iis打开php网页404,遇到IIS7配置PHP出现403和404错误的解决办法
服务器要配置PHP,总是出现403错误.服务器是新装的,操作系统是windows server 2008 R2,装的IIS7. IIS里PHP和本地服务器对比了好几遍,都没到出错的原因,后来通过cmd ...
- Linux 系统使用WordPress开启“固定链接设置”之后部分页面打不开(404)的解决办法...
WordPress系统中我们设定了固定链接设置,选择了自定义结构:http://192.168.10.11/html/%postname%.html 注:%postname%文章标题的别名,文章标题是 ...
- 怎么返回404_seo如果出现404页面怎么办?如何解决?
seo如果出现404页面怎么办?如何解决?很多人对于404页面都司空见惯了,但是要如何找出404错误呢?如何解决呢?下面聚名网小编就为大家介绍一下404页面对于seo是什么. seo如果出现404页面 ...
- 308 permanent redirect怎么解决_「网站」WordPress网站更改固定链接以后怎么解决404错误...
细心的人可能会发现,这篇文章跟如何应公安备案要求将备案编号HTML代码和备案编号图标粘贴到网页的底部位置发布的时间相差并不长,因为我搞定一个问题又跑去搞另一个问题了,之后再一起写的文章 回到正题,Wo ...
- wp-login.php 404页面,WordPress网站如何设置404页面
站长都知道网站搭建好,是需要进行404页面的设置,若没有设置404页面会导致网站流量的流失,那么,WordPress网站如何设置404页面?接下来就关于这个问题为大家进行分析. 404页面也就是客户端 ...
最新文章
- backup restore On Ubuntu
- 崔希凡javaWeb笔记day01~day03(2016年5月20日20:33:54)
- 详细解析SELECT模型
- Java总结:正则表达式
- 无法理解高等数学怎么办?
- 如何写好一个综述,以一个综述为例
- 用idea对git的merge进行撤销
- android看视频掉帧,玩游戏看视频经常卡顿不顺畅?你只需这几步
- EXCEL MATCH函数
- 七大行星排列图片_太阳系八大行星大小及排列顺序
- Unity 3D安装教程
- ARM7、ARM9、ARM11、ARM-Cortex的关系
- Python制作一个12306查票程序脚本(附完整代码,仅供学习参考)
- Java自学经验分享
- docker启动mysql失败(闪退)原因
- LaTeX 数学公式大全
- java吞食天地中武将_在FC吞食天地2里面,哪些武将的基础属性出乎玩家预料
- Android Jetpack之DataBinding+ViewModel+LiveData+Room
- 百度网盘不限速——pandownlode与BaiduPCS-Go
- 用matlab演奏周杰伦的《七里香》