tags: install,wordpress,learn
author: fallseir.lee
date:20060929
description:
分析 wordpress 的代码,分析其自动安装过程,从其内部压榨其可用之处。
=-------------------------------* 跟踪WP的安装 *----------------------------=
安装wordpress就不再重复了
现在我们来看下其文件加载过程
首先、通过 http://localhost/wordpress/ 来访问本地安装的wordpress
1、进入 index.php
在index.php中只是定义的一个默认的样式然后导入wp-blog-header.php文件
2、当加载 wp-blog-header.php 文件时
使用 file_exists 来判断 config.php 文件是否已经配置(存在) 通过dirname(__FILE__)来获取当前目录
使用 strstr 和 全局变量 $_SERVER['PHP_SELF'] 来自动匹配转向文件的位置
使用 die 结束任务并返回错误提示,提示用户到这里http://localhost/wordpress/wp-admin/setup-config.php 来安装配置文件。
其次、在setup-config.php中提示用户如何进行数据库连接配置
1、检测默认配置文件 file_exists('../wp-config-sample.php')
2、检测目录是否可写 is_writable('../')
3、根据外部参数状态进行自动参数填充 isset($_GET['step']) 如果没有设置则设置为默认值
4、根据 switch($step) 指定的向导位置,进行相应的处理
5、使用向导提示用户进行数据库参数设置
5.2、判断配置文件是否已经存在,防止自动覆盖已经存在的配置信息
6、$configFile = file('../wp-config-sample.php'); # 使用 file 提取出文件中的行列
7、设置数据库访问环境 并对数据库环境进行测试
define('DB_NAME', $dbname);
define('DB_USER', $uname);
define('DB_PASSWORD', $passwrd);
define('DB_HOST', $dbhost);
require_once('../wp-includes/wp-db.php'); # 导入数据库处理包,假定这个包有自动监测环紧的部分
8、将配置信息写入到配置文件
fopen('../wp-config.php', 'w'); # 写入配置文件
foreach ($configFile as $line_num => $line) { # 按行读取配置信息
switch (substr($line,0,16)) { # 通过前16字进行配置信息匹配
case "define('DB_NAME'": # 如果包含指定的标识
fwrite($handle, str_replace("wordpress", $dbname, $line)); # 使用对应的新数据进行写入
break;
...
default:
fwrite($handle, $line); # 没有匹配的信息原样写入
fclose($handle); # 关闭文件句柄
chmod('../wp-config.php', 0666); # 修改文件访问模式
配置文件更新成功后提示用户进入安装向导 install.php
然后、开始安装数据库 install.php
1、定义开始安装标记 define('WP_INSTALLING', true);
2、检测 wp-config.php 并加载
3、加载 './upgrade-functions.php' 对上一版数据进行升级(暂时理解为)
4、记录协议名支持可能的https
$schema = ( isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on' ) ? 'https://' : 'http://';
5、组合全路径(PS:将step=2清除了,暂时还不明白为什么)
$guessurl = str_replace('/wp-admin/install.php?step=2', '', $schema . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) );
6、设定http头信息
header( 'Content-Type: text/html; charset=utf-8' ); # 指定处理类型和编码
7、内部统一输出方式
_e('WordPress › Installation'); #将所有的程序输出加壳,以便可以进行统一的处理,比如多语言支持。
8、检测数据是否已经安装
$wpdb->hide_errors(); # 关闭错误输出,在检测时允许出现表不存在的异常
$installed = $wpdb->get_results("SELECT * FROM $wpdb->users"); # 执行sql
if ($installed) die('
'.__('Already Installed').'
'.__('You appear to have already installed WordPress. To reinstall please clear your old database tables first.').'
'); # 使用 __() 封装文字数据获取方式,提供对多语言的支持
$wpdb->show_errors(); # 开启错误输出
9、使用 flush 将一部分数据先送到客户端,让用户最快的看到信息减少用户的等待时间
flush();
将内部的缓存全部送出
// Set everything up
wp_cache_flush();
10、PS:一些不认识的标记
make_db_current_silent();
populate_options();
populate_roles();
11、对经常使用的更新操作进行封装
update_option('blogname', $weblog_title);
update_option('admin_email', $admin_email);
12、设置一些默认数据
// Now drop in some default links
$wpdb->query("INSERT INTO $wpdb->linkcategories (cat_id, cat_name) VALUES (1, '".$wpdb->escape(__('Blogroll'))."')");
$wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_rss, link_notes) VALUES ('http://blogs.linux.ie/xeer/', 'Donncha', 1, 'http://blogs.linux.ie/xeer/feed/', '');");
...
// Default category
$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_count, category_description) VALUES ('0', '".$wpdb->escape(__('Uncategorized'))."', '".sanitize_title(__('Uncategorized'))."', '1', '')");
// First post
$now = date('Y-m-d H:i:s');
$now_gmt = gmdate('Y-m-d H:i:s');
$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, comment_count, to_ping, pinged, post_content_filtered) VALUES ('1', '$now', '$now_gmt', '".$wpdb->escape(__('Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!'))."', '', '".$wpdb->escape(__('Hello world!'))."', '0', '".$wpdb->escape(__('hello-world'))."', '$now', '$now_gmt', '1', '', '', '')");
$wpdb->query( "INSERT INTO $wpdb->post2cat (`rel_id`, `post_id`, `category_id`) VALUES (1, 1, 1)" );
// Default comment
$wpdb->query("INSERT INTO $wpdb->comments (comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_date, comment_date_gmt, comment_content) VALUES ('1', '".$wpdb->escape(__('Mr WordPress'))."', '', 'http://wordpress.org/', '$now', '$now_gmt', '".$wpdb->escape(__('Hi, this is a comment.
To delete a comment, just log in, and view the posts\' comments, there you will have the option to edit or delete them.'))."')");
// First Page
$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, post_status, to_ping, pinged, post_content_filtered) VALUES ('1', '$now', '$now_gmt', '".$wpdb->escape(__('This is an example of a WordPress page, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many pages like this one or sub-pages as you like and manage all of your content inside of WordPress.'))."', '', '".$wpdb->escape(__('About'))."', '0', '".$wpdb->escape(__('about'))."', '$now', '$now_gmt', 'static', '', '', '')");
# PS:从上面的代码可以看书 wp 将数据库操作 都封装到了wpdb对象中,包括可能批量变化的表名,和一些辅助操作$wpdb->escape
13、PS:未知操作
$wp_rewrite->flush_rules();
14、设置管理员信息
// Set up admin user
$random_password = substr(md5(uniqid(microtime())), 0, 6);
# PS:使用md5来生成随机密码呵呵有意思
# 获取email中的用户名
$display_name_array = explode('@', $admin_email); # 不过我经常是使用split来切片一个字符串
$display_name = $display_name_array[0];
# 插入用户
$wpdb->query("INSERT INTO $wpdb->users (ID, user_login, user_pass, user_email, user_registered, display_name, user_nicename) VALUES ( '1', 'admin', MD5('$random_password'), '$admin_email', NOW(), '$display_name', 'admin')");
# PS:$wpdb->insert_id 应该是上一条sql出来的吧
# PS:这个level应该使用来排序的权值吧
$wpdb->query("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES ({$wpdb->insert_id}, '{$table_prefix}user_level', '10');");
# 将权限列表存储 使用php自己的序列化
$admin_caps = serialize(array('administrator' => true));
$wpdb->query("INSERT INTO $wpdb->usermeta (user_id, meta_key, meta_value) VALUES ({$wpdb->insert_id}, '{$table_prefix}capabilities', '{$admin_caps}');");
# 构建mail
$message_headers = 'From: ' . $weblog_title . ' ';
# 使用 sprintf 对模版进行填充
$message = sprintf(__("Your new WordPress blog has been successfully set up at:
%1\$s
You can log in to the administrator account with the following information:
Username: admin
Password: %2\$s
We hope you enjoy your new weblog. Thanks!
--The WordPress Team
http://wordpress.org/
"), $guessurl, $random_password);
# 原来 guessurl 用在这里,在mail中当然不能使用相对路径
# 发送mail
# PS:但是我的 mail 不可用 也许是我配置错了吧 不过我没有设置过阿
@wp_mail($admin_email, __('New WordPress Blog'), $message, $message_headers);
15、PS:又一次清空缓存 而且和前两次用到的不同
wp_cache_flush();
=-------------------------------* PS:终于跟到安装结束了 *----------------------------=
PS:顺了一遍安装的流程,让我们回顾下有什么东西可以留在脑子里
wp的index.php只有两句
/* Short and sweet */ # 短而美妙的
define('WP_USE_THEMES', true);
require('./wp-blog-header.php');
这里的define应该是引导用户可以在这里进行一些全局的设置,在 config 加载之前
这句 require 才是大头,它将所有的处理都封装了
看他的命名
WP_USE_THEMES
前缀wp使用简写
每个单词使用下划线间隔
常量大写
PS:比较常见的命名方式,使用wp前缀应该是给用户最大的可能不出现重名,还可以和其他的插件进行友好的兼容 用户不必再编写插件或进行扩展时需要查看所有可能用到的页面来判断是否会出现命名重复。
wp-blog-header.php
可以看到这个是wordpress的blog的头信息,也可以理解为在处理开始的部分。
这个header好像处理的东西也不多
首先使用$wp_did_header进行重复加载过滤
然后加载config数据
进行预处理
wp(); # 理解为初始化环境
gzip_compression(); # 进行压缩处理
# 加载样式模版
require_once(ABSPATH . WPINC . '/template-loader.php');
PS:今天先到这,没有外链了,我去写篇wp的config分析
UPDATE:本来加了颜色和样式的 但是发布时竟然出现
郁闷啊 我把样式清除了才可以发布 !!