swoft-cloud / swoft

🚀 PHP Microservice Full Coroutine Framework
https://swoft.org
Apache License 2.0
5.58k stars 786 forks source link

实体类,缺字段,不支持NULL #203

Closed ghost closed 6 years ago

ghost commented 6 years ago

实体类取出来的数据,有部分的字段有值,但是被赋空,而且不支持字段内容为NULL。 再个实体类的toArray能改一下吗,不要直接为空的内容就不转换了 @stelin

ghost commented 6 years ago

swoft\vendor\swoft\framework\src\Helper\StringHelper.php 部分字段为空已经找到问题了,这个文件的大小写转换出问题ucfirst方法,导致部分对象名不对 @stelin @inhere

inhere commented 6 years ago

哦 贴下代码呢,欢迎PR :)

ghost commented 6 years ago

swoft\db\src\Helper\EntityHelper.php

@inhere @stelin

这个文件里的

   public static function arrayToEntity(array $data, string $className)
    {
        $attrs    = [];
        $object   = new $className();
        $entities = EntityCollector::getCollector();

        foreach ($data as $col => $value) {
            if (!isset($entities[$className]['column'][$col])) {
                continue;
            }

            $field        = $entities[$className]['column'][$col];
            $setterMethod = 'set' . ucfirst($field);

            $type  = $entities[$className]['field'][$field]['type'];
            $value = self::trasferTypes($type, $value);

            if (method_exists($object, $setterMethod)) {
                // print_r($setterMethod);
                // print_r(PHP_EOL);
                $attrs[$field] = $value;
                $object->$setterMethod($value);
            }
        }
        if (method_exists($object, 'setAttrs')) {
            $object->setAttrs($attrs);
        }

        return $object;
    }

里面ucfirst用的PHP默认的只是转换首字母大写,这个错误的,没有对下划线进行处理,但是你们文件生成工具却是可以的,

swoft\framework\src\Helper\StringHelper.php

再一个我看你们有个StringHelper辅助类,里面有ucfirst方法为什么不统一使用呢,

    public static function ucfirst($string)
    {
        return static::upper(static::substr($string, 0, 1)) . static::substr($string, 1);
    }
ghost commented 6 years ago

@inhere @stelin 实体类,部分字段内容为空一下修复: \192.168.100.130\web\swoft\vendor\swoft\db\src\Helper\EntityHelper.php `public static function arrayToEntity(array $data, string $className) { $attrs = []; $object = new $className(); $entities = EntityCollector::getCollector();

    foreach ($data as $col => $value) {
        if (!isset($entities[$className]['column'][$col])) {
            continue;
        }

        $field        = $entities[$className]['column'][$col];
        $function         = explode('_', $field);
        $function         = array_map(function ($word) {
            return ucfirst($word);
        }, $function);
        $setterMethod = 'set' . implode('', $function);

        $type  = $entities[$className]['field'][$field]['type'];
        $value = self::trasferTypes($type, $value);

        if (method_exists($object, $setterMethod)) {
            $attrs[$field] = $value;
            $object->$setterMethod($value);
        }
    }
    if (method_exists($object, 'setAttrs')) {
        $object->setAttrs($attrs);
    }
    return $object;
}

支持string为NULL类型: public static function trasferTypes($type, $value) { if ($type === Types::INT || $type === Types::NUMBER) { $value = (int)$value; } elseif ($type === Types::STRING) { $value = is_null($value) ? (unset)$value : (string)$value; } elseif ($type === Types::BOOLEAN) { $value = (bool)$value; } elseif ($type === Types::FLOAT) { $value = (float)$value; }

    return $value;
}`

修复toArray转换后为部分字段也不见的问题: \192.168.100.130\web\swoft\vendor\swoft\db\src\Model.php `public function toArray(): array { $entities = EntityCollector::getCollector(); $columns = $entities[static::class]['field'];

    $data = [];
    foreach ($columns as $propertyName => $column) {
        $function   = explode('_', $propertyName);
        $function   = array_map(function ($word) {
            return ucfirst($word);
        }, $function);
        $methodName = 'get' . implode('', $function);
        if (!isset($column['column']) || !\method_exists($this, $methodName)) {
            continue;
        }

        $data[$propertyName] = $this->$methodName();
    }
    return $data;
}

`

建议:文档中表明,不支持其他类型为NULL,如bool,float,int等不支持为NULL,这些应该默认为0或者是false等,原因你们用PHP7的强类型,指明了对象参数类型,所以int等无法传入NULL,不然会报错的。。。不过这样也是挺好的更规整

stelin commented 6 years ago

已修复,db 组件请更新到 v1.1.4