好久没有学习PHP了,今天继续学习源文件 install.php

 // 源文件 /install.php
1407    // display version
1408    if (install_is_cli()) {
1409        echo $options->generator . "\n";
1410        echo 'PHP ' . PHP_VERSION . "\n";
1411    }
  • 如果是在使用客户端运行网站代码就输出typecho和PHP的版本
 // 源文件 /install.php
1413    // install finished yet
1414    if (
1415        install_check('config')
1416        && install_check('db_structure')
1417        && install_check('db_data')
1418    ) {
1419        // redirect to siteUrl if not cli
1420        if (!install_is_cli()) {
1421            install_redirect($options->siteUrl);
1422        }
1423
1424        exit(1);
1425    }
  • 如果三个install_check()函数的返回值都为真,并且不是在用php客户端运行网站代码就执行install_redirect()函数,不管是不是在用PHP客户端运行网站代码都不会再往下执行后面的代码。
 // 源文件 /install.php
440 /**
441  * check install
442  *
443  * @param string $type
444  * @return bool
445  */
446 function install_check(string $type): bool
447 {
448     switch ($type) {
449         case 'config':
450            return file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php');
451         case 'db_structure':
452         case 'db_data':
453             global $installDb;
454 
455             if (empty($installDb)) {
456                 return false;
457             }
458 
459             try {
460                 // check if table exists
461                 $installed = $installDb->fetchRow($installDb->select()->from('table.options')
462                     ->where('user = 0 AND name = ?', 'installed'));
463
464                 if ($type == 'db_data' && empty($installed['value'])) {
465                     return false;
466                 }
467             } catch (\Typecho\Db\Adapter\ConnectionException $e) {
468                 return true;
469             } catch (\Typecho\Db\Adapter\SQLException $e) {
470                 return false;
471             }
472
473             return true;
474         default:
475             return false;
476     }
477 }
  • 由于还未安装完毕case 'config'的返回值为假,case 'db_structure'内无代码,会执行default返回假,case 'db_data':因为$installDb为空返回值为假

最近都没有学习PHP了,今天接着上一章的内容继续学习源文件 install.php

 // 源文件 /install.php
1484
1485 install_dispatch();
1486
  • 在install.php文件末尾调用了install_dispatch()函数,这个函数也是在install.php文件中定义的
 // 源文件 /install.php
1392 /**
1393  * dispatch install action
1394  *
1395  */
1396 function install_dispatch()
1397 {
1398     // disable root url on cli mode
1399     if (install_is_cli()) {
1400         define('__TYPECHO_ROOT_URL__', 'http://localhost');
1401     }
1402
  • 根据install_is_cli()函数的返回值来决定 '__TYPECHO_ROOT_URL__' 变量的值,下面看看install_is_cli()函数的内容
 // 源文件 /install.php
61 /**
62  * detect cli mode
63  *
64  * @return bool
65  */
66 function install_is_cli(): bool
67 {
68     return \Typecho\Request::getInstance()->isCli();
69 }
70
  • 函数install_is_cli()的返回值为布尔型,返回的是\Typecho\Request::getInstance()->isCli()这个函数的值,接着看这个函数是个啥
 // 源文件 /var/Typecho/Request.php
440     /**
441      * @return bool
442      */
443     public function isCli(): bool
444     {
445         return php_sapi_name() == 'cli';
446     }
447
  • 函数isCli()返回的是表达式 php_sapi_name() == 'cli' 的比较结果,php_sapi_name:返回 web 服务器和 PHP 之间的接口类型。继续下面继续看install_dispatch()函数
 // 源文件 /install.php
1403    // init default options
1404    $options = \Widget\Options::alloc(install_get_default_options());
1405    \Widget\Init::alloc();
1406
  • install_get_default_options()在install.php第237行进行了定义,\Widget\Options::alloc()在/var/Typecho/Widget.php第185行进行了定义,\Widget\Init::alloc()与\Widget\Options::alloc()相同
 // 源文件 /install.php
232 /**
233  * list all default options
234  *
235  * @return array
236  */
237 function install_get_default_options(): array
238 {
239     static $options;
240
241     if (empty($options)) {
242         $options = [
            'theme' => 'default',
            'theme:default' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}',
            'timezone' => '28800',
            'lang' => install_get_lang(),
            'charset' => 'UTF-8',
            'contentType' => 'text/html',
            'gzip' => 0,
            'generator' => 'Typecho ' . \Typecho\Common::VERSION,
            'title' => 'Hello World',
            'description' => 'Your description here.',
            'keywords' => 'typecho,php,blog',
            'rewrite' => 0,
            'frontPage' => 'recent',
            'frontArchive' => 0,
            'commentsRequireMail' => 1,
            'commentsWhitelist' => 0,
            'commentsRequireURL' => 0,
            'commentsRequireModeration' => 0,
            'plugins' => 'a:0:{}',
            'commentDateFormat' => 'F jS, Y \a\t h:i a',
            'siteUrl' => install_get_site_url(),
            'defaultCategory' => 1,
            'allowRegister' => 0,
            'defaultAllowComment' => 1,
            'defaultAllowPing' => 1,
            'defaultAllowFeed' => 1,
            'pageSize' => 5,
            'postsListSize' => 10,
            'commentsListSize' => 10,
            'commentsHTMLTagAllowed' => null,
            'postDateFormat' => 'Y-m-d',
            'feedFullText' => 1,
            'editorSize' => 350,
            'autoSave' => 0,
            'markdown' => 1,
            'xmlrpcMarkdown' => 0,
            'commentsMaxNestingLevels' => 5,
            'commentsPostTimeout' => 24 * 3600 * 30,
            'commentsUrlNofollow' => 1,
            'commentsShowUrl' => 1,
            'commentsMarkdown' => 0,
            'commentsPageBreak' => 0,
            'commentsThreaded' => 1,
            'commentsPageSize' => 20,
            'commentsPageDisplay' => 'last',
            'commentsOrder' => 'ASC',
            'commentsCheckReferer' => 1,
            'commentsAutoClose' => 0,
            'commentsPostIntervalEnable' => 1,
            'commentsPostInterval' => 60,
            'commentsShowCommentOnly' => 0,
            'commentsAvatar' => 1,
            'commentsAvatarRating' => 'G',
            'commentsAntiSpam' => 1,
            'routingTable' => serialize(install_get_default_routers()),
            'actionTable' => 'a:0:{}',
            'panelTable' => 'a:0:{}',
            'attachmentTypes' => '@image@',
            'secret' => \Typecho\Common::randString(32, true),
            'installed' => 0,
            'allowXmlRpc' => 2
304         ];
305     }
306
  • 函数定义了$options变量的值
 // 源文件   /var/Typecho/Widget.php
177     /**
178     * alloc widget instance
179     *
180     * @param mixed $params
181     * @param mixed $request
182     * @param bool|callable $disableSandboxOrCallback
183     * @return $this
184     */
185    public static function alloc($params = null, $request = null, $disableSandboxOrCallback = true): Widget
186    {
187        return self::widget(static::class, $params, $request, $disableSandboxOrCallback);
188    }
189
  • 函数返回一个widget类的实例,限于篇幅本章到此结束,下一章接着往下学习。

  • 在用openmediavault的过程中研究了一下zfs文件系统,发现在不同的系统上安装的时候不太一样,这里记录一下作为备忘使用。

我有两台openmediavault主机版本是一模一样的,其中一台直接安装openmediavault-zfs插件就可以使用了。另一台安装失败于是通过ssh连接到两台主机上去看了一下,安装成功的上面zfs版本是2.1.11,安装失败的上面zfs版本是2.0.3,我又上镜像站点查看了一下pool里面的软件包zfs-2.1.11是最新的,于是在安装失败的主机上面增加了一条sid版本的源地址,安装顺利完成后再把sid版的那条源地址注释掉就好了,使用Debian系统或其他发行版的时候有可能遇到类似情况,可以尝试一下这个操作。
下面记录一下相关命令

# 查看相关软件包的版本信息
apt search zfs
# 安装zfs文件系统
apt install openmediavault-zfs
# 或者
apt install zfs-initramfs
# 创建zfs存储池 raidz1最少三块盘 raidz2最少四块盘 raidz3最少五块盘 三种分别有1、2、3块盘作为校验盘
zpool create pool raidz1 sdb sdc sdd
# 导出zpool
zpool export pool
# 或者全部导出
zpool export -a
# 关机把硬盘拔下来后插到其他主机上之后导入
zpool import
zpool import pool
# 查看zpool状态
zpool status
zpool list -v
zfs list
# 硬盘坏了更换硬盘重建:sdb是之前的坏盘,sdf是新的正常硬盘,重建速度非常快
zpool replace pool sdb sdf
  • zfs文件系统非常强大 性能也很好 玩儿NAS硬盘数量大于等于3的话非常建议使用