解决PHP从数据库取出字段全为字符串类型
用 PHP 给 APP 做后台就是有点麻烦,因为 APP 的 JAVA 和 OC 都是强类型的。
PHP 是弱类型的,从 MySQL 数据库取出的字段全为 string 类型的,对 PHP 自身来说,没什么问题,但是对 APP 来说是个灾难。
每次取数据都转换很显然工作量很大。
之前是使用 ThinkPHP 来解决这个问题,但是不太优雅,需要修改框架源码,后来采用了更好的解决方案,直接在 MySQL 连接驱动层面解决问题。
首先确保使用 PDO 连接数据库( PHP 官方推荐)。然后 PDO 设置如下即可:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
对于 MySQL 到 PHP 数据类型的转换关系
MySQL | PHP |
---|---|
FLOAT, DOUBLE | double(float) |
INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT | int |
DECIMAL, NUMERIC | string |
BIGINT (在操作系统 int 范围内是 int,超过范围后是 string) | int | sring |
other.. | string |
下面是 ThinkPHP 框架内处理部分,思路仅供参考。建议采用上面的 PDO 方案。
建议所有涉及到类型转换的都继承 CommonModel 而不是 Model 。
<?php
/**
* Created by PhpStorm.
* User: General
* Date: 2015/8/10/0004
* Time: 09:13
*/
namespace Home\Model;
use Think\Model;
class CommonModel extends Model
{
protected function _after_select(&$resultSet, $options)
{
foreach ($resultSet as &$result) {
$this->_after_find($result, $options);
}
}
protected function _after_find(&$result, $options)
{
foreach ($result as $field => $value) {
$this->_parseType($result, $field);
}
}
}
转换的核心方法是$this->_parseType($result, $field);
这里对 TP 原本的方法进行了修改,原来的有个 BUG。
然后还赠添了一种类型的检测————"tinyint"。
如果有需要检测的字段,做相应添加即可。
/**
* 数据类型检测
* @access protected
* @param mixed $data 数据
* @param string $key 字段名
* @return void
*/
protected function _parseType(&$data,$key) {
if(!isset($this->options['bind'][':'.$key]) && isset($this->fields['_type'][$key])){
$fieldType = strtolower($this->fields['_type'][$key]);
if(false !== strpos($fieldType,'enum')){
// 支持ENUM类型优先检测
}elseif(false !== strpos($fieldType,'tinyint')){//新添加的字段类型
$data[$key] = intval($data[$key]);
}elseif(false === strpos($fieldType,'bigint') && 0 === strpos($fieldType,'int')) {
$data[$key] = intval($data[$key]);
}elseif(false !== strpos($fieldType,'float') || false !== strpos($fieldType,'double')){
$data[$key] = floatval($data[$key]);
}elseif(false !== strpos($fieldType,'bool')){
$data[$key] = (bool)$data[$key];
}
}
}
这个只支持 select()
和 find()
这俩种方法,其他的比如 getField()
等取单个字段的方法不支持,不过单个字段再转换类型的工作量要小很多。
注意!使用原生的 execute()
和 query()
是不支持的,我看了下源码,框架也没对这种原生的方法做更多中间操作。
本作品由 程小白 创作,采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可,可自由转载、引用但需署名作者且注明文章出处。
原文地址:https://www.chengxiaobai.cn/php/solve-the-php-from-the-database-to-remove-the-field-full-of-string-type.html