Summary
This article analyzes the reasons for the error code 200 and PDO serialization exception in response to the failure to publish the Handsome theme time machine. The author successfully solved the problem by downgrading PHP7.4 and modifying the Typecho core file Db.php. At the same time, the author summarized the official troubleshooting and repair methods for common problems such as image upload, emoji support, comment failure, etc., to provide practical guidance for users using this theme.
When I migrated to typecho, I naturally chose handsome. I only bought this theme for no other reason, so I can use all the functions that are available to me, especially the time machine function.
Problem screenshot

Problem Description
publishes content on the WeChat public account and prompts the following error
错误码200<pre><code><h1>Serialization of 'PDO' is not allowed</h1></code></pre>
请求失败500 Server Error: Internal Server Error for url: https://tutouzhang.com/
When publishing content in the browser, the following error message appears:
Serialization of 'PDO' is not allowed
I did not set up my own official account for publishing, so I used only these two publishing methods, and both produced errors. The WeChat official account method produced two errors.
Next, I will explain how I solved these problems.
Official Q
&A;
: Comments/Time Machine Related
- Time Machine is reused from the comment function of typecho, so most of the questions are similar www.ihewro.com Time Machine sends a WeChat message showing "The service provided by this official account is faulty"
- Check whether the author's blog is opened normally
- www.ihewro.com
- If it can be opened normally, it means that the public account service is normal; if it cannot be opened, you can contact the author or wait for a while
Check whether the address you filled in on the authorized platform is exactly the same as your blog address, because the address requested by the official account in the end is the address filled in on the authorized platform, not the address you entered when binding in the official account
For example, the www prefix, http or https should be exactly the same as your blog address
- Before binding a new website to WeChat, you must unbind it first, otherwise problems will occur once one WeChat ID is bound to multiple websites. At this time, you need to contact the author to manually unbind
- When the time machine creates a new label in the sqlite database, the page will get stuck>db->fetchRow($this->select()-> temporarily needs to be fixed by modifying the typecho code.
- Open var/Widget/Feedback.php
$this->db->fetchRow($this->select()->where('coid = ?', $commentId) ->limit(1), [$this, 'push']); - in the typecho directory
$item = $this->db->fetchRow($this->select()->where('coid = ?', $commentId) ->limit(1)); $this->push($item);
Search the row where $this->db->fetchRow($this->select()->where('coid = ?'
- Before modification:
设置——评论——允许使用的HTML标签和属性After modification:
<img src="">
<audio class="" src="" preload>
<video src=""></video>
The comment area cannot be compared and the picture cannot be displayed |Talk about being unable to display pictures/music players/video players
- Backend
usr/uploadsAdd html tagtimeinside - Time Machine/Talk about uploading pictures failed
sudo chmod -R 777 ./ - Check whether there is a
libs/Utils.phpfolder in the(new Imgcompressdirectory in the typecho directory. If there is not one manually created, then give the folder 777 permission
Linux set folder 777 permission command:
- Time Machine adds an image compression process for uploading images. If your server environment does not support the gd extension, the image may be uploaded successfully, but the time machine displays "Upload failed". You can open the theme directory
设置——评论——在评论中使用Markdown语法(选中)and search for设置——评论——允许使用的HTML标签和属性. Comment or delete this line of code.
<blockquote><pre><code><strong><em><h5><h6><a href title><table><thead><tr><th><tbody><td>
The comment area cannot use markdown syntax
background background Add the html tag corresponding to markdown syntax
Talking about the geographical location information is not displayed
- geographical information contains an emoji. Type cho does not support emoji by default. You need to modify the field type of the database:
typecho supports emoji tutorial
- (For details, Baidu typecho supports emoji and has a tutorial) How to delete the time machine
HTTPSConnectionPool(host= xxxx',port=443):Max retries exceeded with url:/Caused by- is the same as comment management. You can delete it in the management of typecho background - comments
httpsUnable to send content to blog time machine - The domain name filled in by the ZZZ authorization platform has an error . The displayed error is generally .
-
The domain name filled in on the authorization platform is , but your blog does not support ssl
http://Make sure that your blog domain namehttps://on thehttps://authorized platform is exactly the same as your site address, such as whether there is www and whether the protocol is http or https
- is the same as comment management. You can delete it in the management of typecho background - comments
- is ultimately
- . Look at the domain name
filled in on the authorization platform. Even if the address entered to bind the information in WeChat is
, the address filled in on the authorization platform is
. In the end, the request is still The address of
- is
- Some servers have made ua judgments, so the request cannot be passed
Some servers have cc protection and requests are prohibited
Specific troubleshooting method for failed comments
- Please upgrade to the latest version of the theme. The problem of comment failure on lower version themes will no longer be maintained Comments fail in two cases:
Notice: Undefined functionhas a specific error message, - An unspecific error that prompts "Comment request failed" or "Comments may be blocked and no feedback information". has a specific error message
- The specific error prompts are divided into the following types: Specific php error output
- , such as prompting that calling a certain function does not existhttps://paugram.com/coding/fix-typecho-ua-problem.html
- and so on, it is usually caused by a certain plug-in. You can check the plug-ins related to comments (such as comment email reminders, etc.) 「Database Query Error」
- , generally there are two situations:
- The comment contains emoji, but the database does not support emoji. You can check here
- typecho supports emoji tutorialtypecho database field problem (generally there will be problems when commenting on mobile QQ WeChat, but it is normal on the computer). For specific methods, see:
- https://paugram.com/coding/fix-typecho-ua-problem.html
CDNThe specific Chinese interception reasonHTML, such as "Sorry, you speak too frequently, please post again later.", or other Chinese error prompts, are normal.CDNIn the comment settings of typecho, the "time interval limit for posting comments from the same IP" is turned oncss,js,imageused the comment anti-spam plug-in to trigger the interception rule- "If the page is cached, the latest comments cannot be displayed"
- , the possible situations are:
- ZZZTT000201The plugin used by ZZZ inserted an old version of jquery.js into the pageIf it conflicts with the theme, you can press F12 to see the error message, such as "colorful mouse". You need to not load jquery in the plug-in settings or disable the plug-in
- cache statically caches the
page, causing the comment function to fail (
- cache recommends only caching static resource files, such as
<meta name="referrer" content="no-referrer" />, - ,
), because you statically cached the page, the page will not be updated, how can your comments be displayed! !
uses the server cache function uses the database cache plug-in uses the page code compression plug-in
If you still have problems after troubleshooting the above processes, you can switch to the default theme (you need to back up the handsome setting data before switching, otherwise it will be cleared). If the default theme does not have this problem and the handsome theme has this problem, you can contact the author to take a look
There is no specific error prompt, prompting "Comment request failed" or "Comments may be blocked and there is no feedback information" Don’t add this line of code to the theme!
If a firewall or the like is turned on, the post request is intercepted. Generally, if the comment contains html code, the firewall will block it.
(In this case, you can turn off the ajax comment switch in the appearance settings - theme enhancement function, and then comment again to view the specific error message)

I found that it did not help me much, so it is better to investigate the problem yourself.
If the problem still cannot be solved after following the above process, you can switch to the default theme (
Be sure to back up the data in the appearance settings interface before switching
). If the default theme comments are normal and the handsome theme is not normal, you can contact me.
Comments/Time Machine hopes to display the latest comments when opening
If you want to open the article/time machine to display the latest comments by default, you need to set up the typecho background - comments, enable paging, and display the first page $_SESSION as the default display when listing. (The theme is forced to "display newer comments in front", which means that the first page is the latest comments, and the last page is the oldest comments)
How to paginate the time machine/review page
typecho backend management - settings - enable paging in comments:
Troubleshooting stepsvar/Typecho/Db.php
I don’t need to explain the error reported by
<?php
namespace Typecho;
use Typecho\Db\Adapter;
use Typecho\Db\Query;
use Typecho\Db\Exception as DbException;
/**
* 包含获取数据支持方法的类.
* 必须定义__TYPECHO_DB_HOST__, __TYPECHO_DB_PORT__, __TYPECHO_DB_NAME__,
* __TYPECHO_DB_USER__, __TYPECHO_DB_PASS__, __TYPECHO_DB_CHAR__
*
* @package Db
*/
class Db
{
/** 读取数据库 */
public const READ = 1;
/** 写入数据库 */
public const WRITE = 2;
/** 升序方式 */
public const SORT_ASC = 'ASC';
/** 降序方式 */
public const SORT_DESC = 'DESC';
/** 表内连接方式 */
public const INNER_JOIN = 'INNER';
/** 表外连接方式 */
public const OUTER_JOIN = 'OUTER';
/** 表左连接方式 */
public const LEFT_JOIN = 'LEFT';
/** 表右连接方式 */
public const RIGHT_JOIN = 'RIGHT';
/** 数据库查询操作 */
public const SELECT = 'SELECT';
/** 数据库更新操作 */
public const UPDATE = 'UPDATE';
/** 数据库插入操作 */
public const INSERT = 'INSERT';
/** 数据库删除操作 */
public const DELETE = 'DELETE';
/**
* 数据库适配器
* @var Adapter
*/
private $adapter;
/**
* 默认配置
*
* @var array
*/
private $config;
/**
* 已经连接
*
* @access private
* @var array
*/
private $connectedPool;
/**
* 前缀
*
* @access private
* @var string
*/
private $prefix;
/**
* 适配器名称
*
* @access private
* @var string
*/
private $adapterName;
/**
* 实例化的数据库对象
* @var Db
*/
private static $instance;
/**
* 数据库类构造函数
*
* @param mixed $adapterName 适配器名称
* @param string $prefix 前缀
*
* @throws DbException
*/
public function __construct($adapterName, string $prefix = 'typecho_')
{
/** 获取适配器名称 */
$adapterName = $adapterName == 'Mysql' ? 'Mysqli' : $adapterName;
$this->adapterName = $adapterName;
/** 数据库适配器 */
$adapterName = '\Typecho\Db\Adapter\\' . str_replace('_', '\\', $adapterName);
if (!call_user_func([$adapterName, 'isAvailable'])) {
throw new DbException("Adapter {$adapterName} is not available");
}
$this->prefix = $prefix;
/** 初始化内部变量 */
$this->connectedPool = [];
$this->config = [
self::READ => [],
self::WRITE => []
];
//实例化适配器对象
$this->adapter = new $adapterName();
}
/**
* @return Adapter
*/
public function getAdapter(): Adapter
{
return $this->adapter;
}
/**
* 获取适配器名称
*
* @access public
* @return string
*/
public function getAdapterName(): string
{
return $this->adapterName;
}
/**
* 获取表前缀
*
* @access public
* @return string
*/
public function getPrefix(): string
{
return $this->prefix;
}
/**
* @param Config $config
* @param int $op
*/
public function addConfig(Config $config, int $op)
{
if ($op & self::READ) {
$this->config[self::READ][] = $config;
}
if ($op & self::WRITE) {
$this->config[self::WRITE][] = $config;
}
}
/**
* getConfig
*
* @param int $op
*
* @return Config
* @throws DbException
*/
public function getConfig(int $op): Config
{
if (empty($this->config[$op])) {
/** DbException */
throw new DbException('Missing Database Connection');
}
$key = array_rand($this->config[$op]);
return $this->config[$op][$key];
}
/**
* 重置连接池
*
* @return void
*/
public function flushPool()
{
$this->connectedPool = [];
}
/**
* 选择数据库
*
* @param int $op
*
* @return mixed
* @throws DbException
*/
public function selectDb(int $op)
{
if (!isset($this->connectedPool[$op])) {
$selectConnectionConfig = $this->getConfig($op);
$selectConnectionHandle = $this->adapter->connect($selectConnectionConfig);
$this->connectedPool[$op] = $selectConnectionHandle;
}
return $this->connectedPool[$op];
}
/**
* 获取SQL词法构建器实例化对象
*
* @return Query
*/
public function sql(): Query
{
return new Query($this->adapter, $this->prefix);
}
/**
* 为多数据库提供支持
*
* @access public
* @param array $config 数据库实例
* @param integer $op 数据库操作
* @return void
*/
public function addServer(array $config, int $op)
{
$this->addConfig(Config::factory($config), $op);
$this->flushPool();
}
/**
* 获取版本
*
* @param int $op
*
* @return string
* @throws DbException
*/
public function getVersion(int $op = self::READ): string
{
return $this->adapter->getVersion($this->selectDb($op));
}
/**
* 设置默认数据库对象
*
* @access public
* @param Db $db 数据库对象
* @return void
*/
public static function set(Db $db)
{
self::$instance = $db;
}
/**
* 获取数据库实例化对象
* 用静态变量存储实例化的数据库对象,可以保证数据连接仅进行一次
*
* @return Db
* @throws DbException
*/
public static function get(): Db
{
if (empty(self::$instance)) {
/** DbException */
throw new DbException('Missing Database Object');
}
return self::$instance;
}
/**
* 选择查询字段
*
* @param ...$ags
*
* @return Query
* @throws DbException
*/
public function select(...$ags): Query
{
$this->selectDb(self::READ);
$args = func_get_args();
return call_user_func_array([$this->sql(), 'select'], $args ?: ['*']);
}
/**
* 更新记录操作(UPDATE)
*
* @param string $table 需要更新记录的表
*
* @return Query
* @throws DbException
*/
public function update(string $table): Query
{
$this->selectDb(self::WRITE);
return $this->sql()->update($table);
}
/**
* 删除记录操作(DELETE)
*
* @param string $table 需要删除记录的表
*
* @return Query
* @throws DbException
*/
public function delete(string $table): Query
{
$this->selectDb(self::WRITE);
return $this->sql()->delete($table);
}
/**
* 插入记录操作(INSERT)
*
* @param string $table 需要插入记录的表
*
* @return Query
* @throws DbException
*/
public function insert(string $table): Query
{
$this->selectDb(self::WRITE);
return $this->sql()->insert($table);
}
/**
* @param $table
* @throws DbException
*/
public function truncate($table)
{
$table = preg_replace("/^table\./", $this->prefix, $table);
$this->adapter->truncate($table, $this->selectDb(self::WRITE));
}
/**
* 执行查询语句
*
* @param mixed $query 查询语句或者查询对象
* @param int $op 数据库读写状态
* @param string $action 操作动作
*
* @return mixed
* @throws DbException
*/
public function query($query, int $op = self::READ, string $action = self::SELECT)
{
$table = null;
/** 在适配器中执行查询 */
if ($query instanceof Query) {
$action = $query->getAttribute('action');
$table = $query->getAttribute('table');
$op = (self::UPDATE == $action || self::DELETE == $action
|| self::INSERT == $action) ? self::WRITE : self::READ;
} elseif (!is_string($query)) {
/** 如果query不是对象也不是字符串,那么将其判断为查询资源句柄,直接返回 */
return $query;
}
/** 选择连接池 */
$handle = $this->selectDb($op);
/** 提交查询 */
$resource = $this->adapter->query($query instanceof Query ?
$query->prepare($query) : $query, $handle, $op, $action, $table);
if ($action) {
//根据查询动作返回相应资源
switch ($action) {
case self::UPDATE:
case self::DELETE:
return $this->adapter->affectedRows($resource, $handle);
case self::INSERT:
return $this->adapter->lastInsertId($resource, $handle);
case self::SELECT:
default:
return $resource;
}
} else {
//如果直接执行查询语句则返回资源
return $resource;
}
}
/**
* 一次取出所有行
*
* @param mixed $query 查询对象
* @param callable|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
*
* @return array
* @throws DbException
*/
public function fetchAll($query, ?callable $filter = null): array
{
//执行查询
$resource = $this->query($query);
$result = $this->adapter->fetchAll($resource);
return $filter ? array_map($filter, $result) : $result;
}
/**
* 一次取出一行
*
* @param mixed $query 查询对象
* @param callable|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
* @return array|null
* @throws DbException
*/
public function fetchRow($query, ?callable $filter = null): ?array
{
$resource = $this->query($query);
return ($rows = $this->adapter->fetch($resource)) ?
($filter ? call_user_func($filter, $rows) : $rows) :
null;
}
/**
* 一次取出一个对象
*
* @param mixed $query 查询对象
* @param array|null $filter 行过滤器函数,将查询的每一行作为第一个参数传入指定的过滤器中
* @return object|null
* @throws DbException
*/
public function fetchObject($query, ?array $filter = null): ?object
{
$resource = $this->query($query);
return ($rows = $this->adapter->fetchObject($resource)) ?
($filter ? call_user_func($filter, $rows) : $rows) :
null;
}
/**
* 序列化时保存必要的配置信息,不包含连接池
*
* @return array
*/
public function __serialize(): array
{
return [
'adapterName' => $this->adapterName,
'prefix' => $this->prefix,
'config' => $this->config
];
}
/**
* 反序列化时恢复配置并初始化适配器
*
* @param array $data 序列化数据
* @return void
*/
public function __unserialize(array $data): void
{
$this->adapterName = $data['adapterName'];
$this->prefix = $data['prefix'];
$this->config = $data['config'];
$this->connectedPool = []; // 重置连接池,防止 PDO 被序列化
// 重新实例化适配器
$adapterName = '\Typecho\Db\Adapter\\' . str_replace('_', '\\', $this->adapterName);
if (!class_exists($adapterName)) {
throw new DbException("Adapter {$adapterName} is not available");
}
$this->adapter = new $adapterName();
}
}
500, but my browser can access it, but the official account cannot, so I suspected it was the author’s problem. Later, I tried to change from php8.0 to php7.4 to solve the problem.
- The error code :__serialize() official account error code 200 indicates that the response was successful, but the page returned is wrong. Then I suspect that typecho or handsome returned to the normal state. In fact, it may still be a 500 error. $connectedPool This browser error occurs when trying to serialize a PDO object. PDO is a database connection class of PHP and cannot be serialized. $adapter I guess: session management (
- $_SESSION:__unserialize() ), caching mechanism, object persistence, or a class that includes PDO when saving state. $connectedPoolBecause of this conjecture, I disabled all plug-ins for troubleshooting, but the problem was still not found, so I pointed the finger at typecho. I seriously suspected that his version 1.2.1 had been changed. $adapterperfect solution selectDb() found
var/Typecho/Db.php
-
Paste the following code to overwrite it. It is strongly recommended to back up the file :__serialize() working principle __unserialize() When serializing Db :
-
__serialize():
- __serialize()returns a value that does not contain $adapterName、$prefix $connectedPool $configand $connectedPool $adapter $adapter。
- __unserialize()array to avoid trying to serialize PDO. $connectedPoolwhen deserializing: $adapter __unserialize()
-
Restore configuration from data, reset $connectedPool











