如何制作一个PHP结构,不抱怨未定义属性的请求?

时间:2017-08-10 13:04:14

标签: php

我有一堆可选设置,而且我厌倦了检查issetproperty_exists

在Laravel中,如果我要求某个模型或请求中不存在的属性,我会收到null并且没有投诉(错误)。我怎样才能对我的数据结构做同样的事情。

如果我尝试使用数组,我就不能做简单的$settings['setting13'],我必须用空值预先填充它,或者isset($settings['setting13']) ? $settings['setting13'] : ''$settings['setting13'] ?? null。如果我尝试一个对象(new \stdClass()),$settings->setting13仍会向我发出未定义属性的警告。

如果要求提供一个它没有的属性,我怎样才能使一个类响应null或空字符串?

2 个答案:

答案 0 :(得分:2)

简单地做Laravel的工作,创建一个处理数据结构的类,如果键存在则返回一个值,如果不存在则返回其他内容。

我将用一个示例类来说明(这个类支持"点表示法"访问数组键):

class MyConfigClass
{
    protected $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function get($path = '', $default = null)
    {
        if(!is_string($path))
        {
            return $default;
        }


        // There's a dot in the path, traverse the array
        if(false !== strpos('.', $path))
        {
            // Find the segments delimited by dot
            $segments = explode('.', $path);

            $result = $this->data;

            foreach($segments as $segment)
            {
                if(isset($result[$segment]))
                {
                    // We have the segment
                    $result = $result[$segment];
                }
                else
                {
                    // The segment isn't there, return default value
                    return $default;
                }
            }

            return $result;
        }

        // The above didn't yield a result, check if the key exists in the array and if not - return default
        return isset($this->data[$path]) ? $this->data[$path] : $default;
    }
}

使用:

$my_structure = [
    'url' => 'www.stackoverflow.com',
    'questions' => [
        'title' => 'this is test title'
    ]
];

$config = new MyConfigClass($my_structure);

echo $config->get('url'); // echoes www.stackoverflow.com
echo $config->get('questions.title'); // echoes this is test title
echo $config->get('bad key that is not there'); // returns null

答案 1 :(得分:2)

还有可能像Jon Stirling在评论中提到的那样创建包装器。这种方法可以保持代码清洁,还可以通过继承添加功能。

<?php
class myArray implements ArrayAccess {
    private $container; 

    function __construct($myArray){
        $this->container = $myArray;
    }
    public function offsetSet($offset, $value) {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    public function offsetExists($offset) {
        return isset($this->container[$offset]);
    }

    public function offsetUnset($offset) {
        unset($this->container[$offset]);
    }

    public function offsetGet($offset) {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }

}

$settings = array("setting1"=>1,"setting2"=>2,"setting3"=>3);

$arr = new myArray($settings);

echo $arr['setting1'];
echo "<br>";
echo $arr['setting3'];
echo "<br>";
echo $arr['setting2'];
echo "<br>";
echo "------";
echo "<br>";
echo  $arr['setting4'] ?:"Value is null";