RedBean返回tinyint列为字符串及isDefault转换异常问题求助
RedBeanPHP 使用问题解答
问题背景
现有photos表结构如下:
+----------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | account_number | varchar(20) | NO | | NULL | | | photo | text | YES | | NULL | | | isDefault | tinyint(1) | YES | | 0 | | +----------------+-------------+------+-----+---------+----------------+
编写的PHP脚本:
<?php require 'rbconnect.php'; $photos = R::findOne('photos'); var_dump($photos); $photos->id = intval($photos->id); $photos->isDefault = intval($photos->isDefault); echo json_encode($photos); ?>
执行后var_dump($photos)的片段:
object(RedBeanPHP\OODBBean)#17 (11) { ["properties":protected]=> array(4) { ["id"]=> string(1) "1" ["account_number"]=> string(10) "1234567890" ["photo"]=> string(17) "sample_photo_data" ["isDefault"]=> string(1) "0" } ["__info":protected]=> array(8) { ["type"]=> string(6) "photos" ["sys.id"]=> string(2) "id" ["sys.orig"]=> array(4) { ["id"]=> string(1) "1" ["account_number"]=> string(10) "1234567890" ["photo"]=> string(17) "sample_photo_data" ["isDefault"]=> string(1) "0" } ["tainted"]=> bool(false) ["changed"]=> bool(false) ["changelist"]=> array(0) { } ["model"]=> NULL ["data.bundle"]=> array(0) { } } // 其余属性省略 }
生成的JSON结果:
{"id":1,"account_number":"1234567890","photo":"sample_photo_data","isDefault":"0","is_default":0}
疑问
- 如果不进行类型转换,
id和isDefault返回的都是String类型,它们不应该是int类型吗? - 类型转换对
id有效,但对isDefault无效,转换isDefault时反而生成了另一个字段is_default。
解答
问题1:数值类型字段返回字符串的原因
RedBeanPHP 默认以字符串形式返回数据库数值类型,这是它的设计策略:采用延迟类型转换,避免不必要的类型操作,同时兼容不同数据库的数值处理差异(比如大整数的跨库兼容问题)。
如果需要自动保留数据库原生类型,可在初始化连接后添加以下配置,让PDO直接返回对应数据类型:
// 启用PDO原生类型返回 R::getDatabaseAdapter()->getDatabase()->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); R::getDatabaseAdapter()->getDatabase()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
问题2:isDefault转换无效并生成is_default的原因
这是RedBeanPHP的驼峰-蛇形命名自动映射规则导致的:
- RedBeanPHP默认会把PHP中的驼峰命名属性(如
isDefault)自动映射为数据库的蛇形命名字段(is_default)。 - 你的数据库字段是驼峰命名的
isDefault,但RedBeanPHP依然会自动转换为is_default来访问,直接给$photos->isDefault赋值时,它会认为你要操作一个新的、不存在的字段,因此出现JSON中同时存在isDefault和is_default的情况。
解决方法有两种:
- 修改数据库字段名:将
isDefault改为is_default,符合RedBeanPHP的默认命名规范,之后直接用$photos->is_default访问即可。 - 关闭命名自动转换:在初始化时关闭驼峰转蛇形规则,代码如下:
R::useFacadeBeanHelper(false);
关闭后即可直接用$photos->isDefault对应数据库的isDefault字段,类型转换也会正常生效。
内容的提问来源于stack exchange,提问作者Noor
相关产品推荐
相关产品推荐

