如何制作一个PHP结构,它不会';不要抱怨未定义属性的请求?
我有一大堆可选设置,我厌倦了检查如何制作一个PHP结构,它不会';不要抱怨未定义属性的请求?,php,Php,我有一大堆可选设置,我厌倦了检查isset和property\u是否存在 在Laravel中,如果我请求一个模型或请求中不存在的属性,我会得到null,并且没有投诉(错误)。如何对我的数据结构执行相同的操作 如果我尝试数组,我不能做简单的$settings['setting13'],我必须用空值预先填充它,或者做isset($settings['setting13'])$设置['setting13']:''或$settings['setting13']??空。如果我尝试一个对象(new\stdC
isset
和property\u是否存在
在Laravel中,如果我请求一个模型或请求中不存在的属性,我会得到null
,并且没有投诉(错误)。如何对我的数据结构执行相同的操作
如果我尝试数组,我不能做简单的$settings['setting13']
,我必须用空值预先填充它,或者做isset($settings['setting13'])$设置['setting13']:''
或$settings['setting13']??空
。如果我尝试一个对象(new\stdClass()
),则$settings->setting13
仍会对未定义的属性发出警告
我如何使一个类在被要求提供它没有的属性时响应null
或空字符串
!empty($settings['setting13']) ? $settings['setting13'] : ''
可以替换为
$settings['setting13'] ?: ''
只要您想要打印的内容和您想要检查的内容存在,都是相同的表达式。这并不是有史以来最干净的事情——检查任何东西的存在——但它相当清晰,可以链接:
echo ($a ?: $b ?: $c ? $default ?: '');
然而,您并不是第一个“厌倦了检查isset
和属性_是否存在”的人,只是我们还必须这样做,否则我们会在最不经意的时候得到意想不到的结果
这不是为了节省时间键入代码,而是为了节省时间而不是调试。
编辑:正如评论中所指出的,我用isset()
而不是!empty()
写了第一行。因为?:
返回左操作数,如果它等于true
,那么它当然与未检查的变量不兼容,您至少必须事先检查是否存在。可以测试它的空性。
如果左操作数存在并且与NULL
不同,则返回其左操作数的运算符是?
,它可以以与?:
相同的方式链接。当然不是最好的方法,但您可以在php中像这样使用错误抑制器:
$value=@$settings['setting13'];
如果未设置$settings['setting13']
且未报告未定义的变量通知,则将$value
完全设置为NULL
对于对象,您应该只调用类中未定义的属性。只需执行Laravel所做的操作,创建一个处理数据结构的类,如果键存在,该类将返回一个值,如果键不存在,则返回其他值
我将用一个示例类来说明(该类支持访问数组键的“点表示法”):
使用:
正如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";
对于对象,您可以在对象中实现magic _call/__get方法来为您执行这些检查,并实现arrayaccess接口以允许数组访问。您在什么结构中请求不存在的变量?@JonStirling感谢关键字,现在我发现了Laravel模型是如何做到这一点的。这是som吗E如果不明确定义一个类怎么办?我只需要一个地方,但似乎stdClass
不支持神奇的方法。@GrumpyCrouton简化示例-表单上的文本字段。如果它们是通过各种方式设置的(获取查询、用户首选项),我需要填充它们。因此,我从GET中获取一些内容,为特定字段添加一些内容,并在视图中为文本字段设置name=“field5”value=“”
。我真的希望避免在那里进行检查。您是对的,它不适用于stdClass,您必须使用您在Laravel中发现的自己的类。:)我在“纯”中这样做没有问题“PHP文件。但是在视图中-要在每个文本输入中重复检查。。。它看起来非常丑陋,并且破坏了可读性。解决方法是在所有可能的数组键前加上null
s似乎引入了更多断点……这根本不是什么黑魔法,只是在?
之前和之后加上相同表达式的语法糖。记住这一点,因为它只适用于标量。数组实体和对象属性仍然需要您使用函数来检查是否存在。虽然我个人更喜欢较长的语法,但对我来说,该快捷方式不直观,需要花费一些时间来阅读和理解。。。我投票支持最后那句粗体的话。我希望我能将该语句上推两次。@David我通常在视图中使用它,在视图中我打印了很多可能为空的字符串。事实上,这是我发现它可读性和安全性都足以提高效率的唯一一种情况,因为它允许我避免PHP冗长,以免让我的视图变得凌乱,同时又不会失去安全性。在pute PHP代码中,这些快捷方式绝对是不礼貌的。?:
不会抑制关于不存在索引的警告!唯一执行此操作的操作员是?
。
$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
<?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";