14.Laravel取出mysql数据全部被转成string类型问题

2016.10.14


1.问题描述

今天做博客时显示用户信息,在性别栏对数据库中的user_sex数据进行判断,是0显示女,是1显示男,但是在用empty()判断非空时 0 被判定为空,所以改用了 === 来判断是男还是女。但是发现结果既不是0也不是1。


2.解决过程


使用dd()或者var_dump()进行打印发现取出的user_sex数据类型为string,而我数据库中使用的tinyint。进一步观察发现无论数据库中数据类型是什么,取出的数据全是string类型。


通过上网查询发现PHP取出的mysql数据默认都会转换为string,这是PHP语言设计的原因,不是laravel的原因。然后查询laravel手册的Eloquent ORM发现有个属性转换的功能,即在模型中定义一个数组变量


/**
* 应该被转化为原生类型的属性
*
* @var array
*/
protected $casts = [
'user_sex'=> 'int',
];


然后当访问被设置的user_sex属性时,他会将类型自动转换为int类型。


通过测试发现当
$user = App\User::find(1);
dd($user);
时,输出的数据仍然全部为string类型,user_sex并没有被转换。


而只有当你访问$user->user_sex时才会触发类型转换:

$user = App\User::find(1);
dd($user->user_sex); //打印结果为 (int)1


手册中给出的例子是json转array。
protected $casts = [
'option' => 'array',

];


数据库中存储的option为json类型,当访问option属性时自动被转换为array类型,


而且当设置option属性的值时会将给定的array自动转换为json进行存储。这样可以省去jsonencode()和jsondecode()操作,更加方便。


$user = App\User::find(1);
$options = $user->options; //触发自动转换,将json转换为array
$options['key'] = 'value';
$user->options = $options; //触发自动转换,将array转换为json
$user->save();


3.扩展


在查询时发现PHP默认会将mysql取出的数据全部转换为string类型。在这篇文章找到了原因和解决办法


原文链接:http://www.druidcoder.cn/2016/05/10/mysql-driver/


大致意思为


PHP有两种驱动:libmysqlclient(MySQL client server library )和mysqlnd(MySQL native driver )。

三种扩展(api):mysql,mysqli,PDO


对于libmysqlclient驱动是没办法得到mysql的数据类型,取出的数据都会转换为string,而对于mysqlnd驱动是可以得到mysql的数据类型,但是默认仍会转换为string,需要手动进行设置。

在PHP5.3版本之前默认使用的是libmysqlclient驱动,5.3之后改为mysqlnd,所以在5.3版本之前无法得到数据类型,而在5.3之后,mysqli和PDO扩展可以得到数据类型,需要进行设置,但mysql扩展却不行。


通过mysqli的MYSQLI_OPT_INT_AND_FLOAT_NATIVE参数设置得到数据类型:
    $mysqli = new mysqli('127.0.0.1', 'root', '', 'test');
    $query = "select * from test_int";
    $mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, 1); 
    $result = $mysqli->query($query);
    $info = $result->fetch_array();

    var_dump($info);


通过pdo:
    $pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', '');
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
    foreach ($pdo->query('select * from test_int') as $row) {
    var_dump($row);
}


4.总结


PHP取出mysql数据默认会全部转换为string类型,一般情况下不会有什么问题,但是在进行 === 等数据类型判断时应注意这个问题。


mysql扩展已经被官方废弃,以后项目中应避免使用。

你可能感兴趣的:(学习笔记)