php PDO驱动 mysqlnd折腾记

Reading time ~1 minute

    昨天晚上折腾的laravel的时候,又是发现本地的laravel的model自动对字段有类型识别,感到很奇怪,在想难不成是每次都直接先拉了一次表信息,那这样岂不是代价太大了,于是趁着这次有时间,好好的钻研了一番。

    一路跟着laravel的流程一点点的打log,发现了下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
public function select($query, $bindings = [], $useReadPdo = true)
{
    return $this->run($query, $bindings, function ($me, $query, $bindings) use ($useReadPdo) {
        if ($me->pretending()) {
            return [];
        }

        // For select statements, we'll simply execute the query and return an array
        // of the database result set. Each element in the array will be a single
        // row from the database table, and will either be an array or objects.
        $statement = $this->getPdoForSelect($useReadPdo)->prepare($query);

        $statement->execute($me->prepareBindings($bindings));

        return $statement->fetchAll($me->getFetchMode());
    });
}

    很明显,这里直接就是操作pdo执行了,然后那句execute的结果发现就已经是识别出数据类型了的,也就是说,PDO做了这件事,不像是laravel自己做的,难不成是laravel升级之后怎么配置了下PDO(因为这次本地用的是最新的laravel)?甚感诧异之下,我又跑服务器上去运行了下,发现服务器给的结果还是没有数据类型的,当时我就**了。

    想想看,我跟服务器上的php版本确实是不大相同,我是php5.5.25,服务器是5.5.9,但就一个小版本号的差距不至于吧!于是十分蛋疼的在Google上好好搜了一番,结果发现在php5.3之后,php mysql换了个mysqlnd的驱动,这个驱动本身提供了对数据类型的识别,而之前的libmysql不支持,可是我都已经php5.5了,怎么还没有,也是醉了!

    为了确认问题,又在stack overflow上找了个测试mysql到底用的啥驱动的代码跑了下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
$hasMySQL = false;
$hasMySQLi = false;
$withMySQLnd = false;
$sentence='';

if (function_exists('mysql_connect')) {
    $hasMySQL = true;
    $sentence.= "(Deprecated) MySQL <b>is installed</b> ";
} else
    $sentence.= "(Deprecated) MySQL <b>is not</b> installed ";

if (function_exists('mysqli_connect')) {
    $hasMySQLi = true;
    $sentence.= "and the new (improved) MySQL <b>is installed</b>. ";
} else
    $sentence.= "and the new (improved) MySQL <b>is not installed</b>. ";

// 这句是关键,只有mysqlnd才提供了mysqli_fetch_all
if (function_exists('mysqli_fetch_all')) {
    $withMySQLnd = true;
    $sentence.= "This server is using MySQLnd as the driver.";
} else
    $sentence.= "This server is using libmysqlclient as the driver.";

echo $sentence;

    果然就发现服务器上用的是libmysql,当时那个愤怒啊,之前蛋疼了好久的数据库为啥就不能自动识别下类型的问题,竟然是因为用了一个这么老的驱动,阿里云是闹哪样啊,为啥默认装这种老旧的东西!!!

    不过不管咋滴,先把驱动换掉再说,网上看到各种都是说mysql编译的时候改参数,不过apt-get看了下,发现有php5-mysqlnd这个玩意,于是果断直接装了,然后再运行脚本发现已经好了(apt-get大法好(>_>),自动enable mod+restart fpm)。

    最后想想的话,laravel的那个$casts功能其实就没有我之前觉得的那么重要了,反正类型已经识别出来了,不过,设置一下也还是有好处的,可以保证取出来的model属性被我们修改后也一定是正确的数据类型,毕竟PDO只能保证取出数据的初始数据类型是对的,并且想来bool类型也识别不了,因为mysql就没bool……

挂载网络文件夹后网络故障时文件操作命令卡死

挂载 NFS 或者 Samba 的时候,经常会由于网络故障导致挂载好的链接断掉。此时如果尝试进行 ls、cd、df 等各种命令,只要与此目录沾上边,就会卡住。如果使用了类似 oh-my-zsh 这种配置的,只要在网络目录中,弹出命令提示符前就会直接卡住。这个时候第一反应就是...… Continue reading

路由折腾记 第四弹

Published on September 02, 2017