假设我有几个模型使用MySQL的位字段存储一些标志。
我知道通过以下操作可以很容易地将其转换为bool:

$myBoolFlag = (ord($model->myFlag) == 1) ? true : false;

我正在寻找某种方法使它自动映射到布尔属性。
请有人告诉我,在我的项目中,有一个比为每个位字段创建setter和getter更好的方法。我敢打赌,Phalcon在数据库服务或类似的东西中有一些神奇的配置。。。

最佳答案

我处理类似问题的方法是在每个模型中创建映射数组并处理它们。更具体地说:

<?php
/**
 * Model.php
 *
 * Model
 *
 * @author      Nikos Dimopoulos <[email protected]>
 * @since       2012-12-12
 * @category    Library
 *
 */

namespace NDN;

use \Phalcon\DI\FactoryDefault as PhDi;
use \Phalcon\Mvc\Model as PhModel;

class Model extends PhModel
{
    private $meta = [];

    /**
     * Some init stuff
     */
    public function initialize()
    {

        // Disable literals
        $this->setup(['phqlLiterals' => false]);
    }

    /**
     * Universal method caller. This checks the available methods based on
     * the fields in the meta array and returns the relevant results
     *
     * @author  Nikos Dimopoulos <[email protected]>
     * @since   2015-02-15
     *
     * @param   string      $function
     * @param   array|null  $arguments
     *
     * @return  mixed|void
     * @throws  \Exception
     */
    public function __call($function, $arguments = null)
    {
        // $function is something like getId, setId, getName etc.
        $metaFunction = substr($function, 3);
        $field        = $this->getMetaFunctionToField($metaFunction);

        if ($field) {

            $prefix    = substr($function, 0, 3);
            $fieldName = $field['field'];

            switch ($prefix) {
                case 'get':

                    /**
                     * Data manipulation here if needed
                     */
                    $value = $this->getField($fieldName);
                    $value = $this->metaFieldValidate($field, $value);

                    return $value;
                    break;

                case 'set':

                    /**
                     * Data manipulation here
                     */
                    $value = $this->metaFieldValidate($field, $arguments);

                    $this->setField($field, $value);
                    break;
            }

        } else {
            throw new \Exception('Function does not exist');
        }
    }

    /**
     * -------------------------------------------------------------------------
     * PROTECTED METHODS
     * -------------------------------------------------------------------------
     */

    /**
     * Gets a field from the model with the correct prefix
     *
     * @param $name
     *
     * @return mixed
     */
    protected function getField($name)
    {
        return $this->$name;

    }

    /**
     * Sets a field in the model
     *
     * @author  Nikos Dimopoulos <[email protected]>
     * @since   2014-02-15
     *
     * @param   string  $field
     * @param   mixed   $value
     */
    protected function setField($field, $value)
    {
        $this->$field = $value;
    }

    /**
     * Returns the DI container
     *
     * @author  Nikos Dimopoulos <[email protected]>
     * @since   2014-02-22
     *
     * @return  mixed
     */
    public function getDI()
    {
        return PhDi::getDefault();
    }

    /**
     * Accesses the internal array map to provide the field name from a function
     *
     * @author  Nikos Dimopoulos <[email protected]>
     * @since   2014-02-27
     *
     * @param   string  $prefix     The prefix of the table
     * @param   string  $function   The aliased function
     *
     * @return  string  The field name (i.e. tnt_id)
     *          bool    False if not found
     */
    public function getMetaFunctionToField($function)
    {
        if (array_key_exists($function, $this->meta)) {
            return $this->meta[$function];
        }

        return false;
    }

    /**
     * Validates a setter value based on each field's type
     *
     * @author  Nikos Dimopoulos <[email protected]>
     * @since   2014-02-17
     *
     * @param   string  $field  The field to check
     * @param   mixed   $value  The value of the field
     *
     * @return bool|int|string
     */
    protected function metaFieldValidate($field, $value)
    {
        // Find the validator
        $validator = $field['validator'];

        switch ($validator)
        {
            case 'int':
                $return = intval($value);
                break;
            case 'bit':
                $return = (ord($value) == 1) ? true : false;
                break;
            case 'bool':
                $return = (bool) $value;
                break;
            case 'decimal':
                $return = (float) $value;
                break;
            case 'string':
                $return = (string) $value;
                break;
            case 'datetime':
                /**
                 * @todo check datetime validator
                 */
                $return = (string) $value;
                break;
            default:
                $return = $value;
                break;
        }

        return $return;
    }

}

示例User模型如下所示
<?php
/**
 * User.php
 *
 * User
 *
 * @author      Nikos Dimopoulos <[email protected]>
 * @since       2014-03-08
 * @category    Models
 *
 */

namespace NDN;

use \NDN\Model as NDNModel;

class Model extends NDNModel
{
    public function initialize()
    {
        /**
         * This is where I will set the field map
         *
         * The key of the array is the function name without
         * the prefix. So for instance if you want getName()
         * to return the user.name you use Name as the key
         */
        $this->data = [
            'Id' => [
                'field'     => 'user_id',
                'validator' => 'int',
            ],
            'Name' => [
                'field'     => 'user_name',
                'validator' => 'int',
            ],
            'IsMarried' => [
                'field'     => 'user_is_married',
                'validator' => 'bit',
            ]
        ];

        parent::initialize();
    }
}

关于php - 自动将MySQL位字段映射到bool属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22260410/

10-11 11:11