PHP isset - 不区分大小写的测试案例

3

我有一个配置对象,其中包含各种对象的设置。我的类在运行时生成,只要我想要实例化一个还没有创建的类的对象,它们就依赖于配置对象来了解哪些属性是必填的以及其他一些信息。可以这样考虑:

Config
   ->Class1
      ->Attributes
           ->id
              ->Mandatory: true
           ->imagesource
              ->Mandatory: true
           .................
   ->Class2
     ..........................   

我有一个方法,validateObject(),它会检查对象的必填值是否都已设置,例如:

function validateObject($object){
   $config = configObject[get_class($object)];
   foreach($config->attributes as $attrName => $attrVal){
      if($attrVal->mandatory == true){
         if(!isset($object->$attrName){
            throw Error();
         }
      }
   }
}

到目前为止,一切都很顺利。现在,我的配置对象将属性名称转换为驼峰式大小写。我决定让程序员使用任何大小写方式,最终只想检查对象是否有任何属性,将其转换为小写后,与转换为小写的 Config 上的属性匹配。

我当前的解决方案可能是这样的:

function validateObject($object){
   $config = configObject[get_class($object)];
   foreach($config->attributes as $attrName => $attrVal){
      if($attrVal->mandatory == true){
         $lowercaseAttr = str_to_lower($attrName);
         foreach($object as $key => $value){
           if(str_to_lower($key) == $lowercaseAttr){
              //don't throw, move to the next attribute in config
           }
         }
      }
   }
}

这样做可以完成任务,但需要更多的工作。我正在寻找更优雅的解决方案...希望我没有让你感到困惑,谢谢你的帮助。

也许你应该将所有属性转换为一个大小写(可能是小写)。 - Oyeme
我不想这样做,因为程序员会失去追踪它的能力。 :) - André Alçada Padez
你想要类似于areEqual('camelCase', 'camel_case')这样的东西吗? - Álvaro González
3个回答

2
我唯一能想到的方法是向您的类中添加一个类似于以下的函数:
  public function check($p){
    $props =get_object_vars($this);
    $array_to_search;
    foreach($props as $key=>$prop){
        $array_to_search[strtolower($key)] = strtolower($key);
    }
    echo "prop :".array_key_exists(strtolower($p),$array_to_search);
}

然后调用。
  $obj->check("thingtwo");

数组位可能需要优化,我只是快速拼凑出来看看是否适合您的需求。如果你有很多类别,那么这个函数可以独立存在,并且你可以传入一个对象。

  function check($obj,$p){
    $props =get_object_vars($obj);
    $array_to_search;
    foreach($props as $key=>$prop){
        $array_to_search[strtolower($key)] = strtolower($key);
    }
    echo "prop :".array_key_exists(strtolower($p),$array_to_search);
}

    check($myobj, "propertyname");

如果属性存在但为 null,则以上代码将返回 true。您可以通过更改函数来检查该值。
 function check($obj,$p){
    $props =get_object_vars($obj);
    $array_to_search;
    foreach($props as $key=>$prop){
        $array_to_search[strtolower($key)] = $prop;
    }
    echo "prop :".isset($array_to_search[strtolower($p)]);
}

$array_to_search; 这个语句是做什么用的? - meze
1
它只是一个由所有属性填充的数组。可能需要显式地将其转换为数组。$array_to_search = new Array();但我只有时间匆忙地组合和测试了它。 - TommyBs
$array_to_search; 这种写法实际上没有任何意义,是毫无意义的。你应该总是明确地声明它是一个数组 $array_to_search = array(); - meze
1
我指出我很快地把这个东西拼凑起来了,而且我甚至说过数组的东西可以被优化。然后我在回复你的评论时进一步扩展了这一点。当时我正要出门,但我想尝试帮助原始的发布者。 - TommyBs

1

PHP中的数组键是区分大小写的,正如您所知道的那样,那么当开发人员犯了错误,例如重复现有设置时会发生什么呢?

一些自定义配置:

$attributes = array(
    'settingOne' => array(/* stuff */),
    // ...
    'settingone' => array(/* different stuff */)
);

现在,当开发人员尝试编辑设置时,他可能会编辑settingOne,也可能会编辑settingone。 如果他恰好没有编辑您的代码正在读取的那个(这很可能是数组中的第一个),则他的更改将不起作用,并且他手头上有一个非常难找到的错误。

虽然这是您的设计,但如果我以这种方式进行某些操作,我将要求配置数组键与我预期的完全匹配。 这可以在您创建的任何文档中明确强调,并解决所有问题,因为您可以简单地使用isset()。 我认为,大多数开发人员都习惯了这种方法,因为这是大多数现有API的工作方式。


这很有道理。但我的问题来自另一个方面。所有的文档和使用者都是用小写字母。如果我按照你说的去改,那么每个人都需要更改一切。我现在尝试的方法有点奇怪,但程序员有责任坚持第一选择。 - André Alçada Padez
如果它们现在都使用小写,而您不希望它们改变,为什么不将您期望的键大小写更改为小写呢?然后您仍然可以使用 isset() - FtDRbwLXw6
这是各种语言API的“合资企业”,我们有.Net、Java、PHP、Javascript,并且必须保持一致。猜猜谁是需要遵守规定的弱者? :) - André Alçada Padez
1
如果是这种情况,那么你现在所做的方式确实是唯一可行的方式。 - FtDRbwLXw6

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接