使用PHP数组输入安全类型

大家好,我将告诉您我自己的自行车,以方便使用PHP数组。

类型提示


类型提示出现在PHP7中,它使IDE可以对代码进行更好的静态分析,提高了代码的质量(或正确地说“ 它变得更好 ”?)。

当然,在早期,IDE可以在代码的注释中编写提示,但是现在类型已经成为代码的一部分,现在可以重构了,不必担心您会忘记某些地方(在重命名类和接口的意义上进行重构)。

除了可以指定输出类型这一事实外,还可以指定输入参数的类型。

但是,除了具有不错的功能之外,类型提示还附加了职责,即,变量的类型确实应如方法签名中所示。

如果不检查类型,则可能会在方法和构造函数中出现错误(特别是设计器中的错误令人鼓舞)。

手动编写支票非常乏味,我决定使这项业务自动化,但不是通过验证,而是通过强制转换为所需的类型。

在我的工作中,我常常不得不从头开始编写,通常是原型,解析器或新数据源的ETL,实际上也是解析器。

当然,您可以使用数组(例如,当您从* .csv中读取内容时),可以通过ORM使用数据库,但是对于我的任务来说太麻烦了,这对我来说很方便,可以通过PDO使用数据库,这再次为您提供了数组中的数据。 “收藏夹” Bitrix不能返回数组以外的数据。

无论您必须如何从数组检索数据。 所以我写了一个包装器来处理数组。

为了不将代码从一个项目复制到另一个项目,我Composer设计了软件包

composer require sbwerewolf/language-specific 

价值处理者


我的第一个要求是始终知道我将得到哪种类型。 当然,在此之前,我们仍然必须通过索引来获取值,因此得出的结论是,我们需要get ()方法。

现在我们需要强制转换的方法,PHP中没有很多类型,我们得到了以下方法:

  1. int()
  2. str()
  3. 布尔()
  4. 双()

有时会遇到数组,所以让它用于数组:

  • 数组()

有时,您只需要按原样获取元素:

  • asIs()

有时可能没有带有给定索引的元素,然后您需要使用默认值:

  • 默认()

数组处理程序


下一个要求是能够将数组从一个值简化为恰好此值。

我将向您展示文档中的示例:

 $connection = new PDO ($dsn,$login,$password); $command = $connection->prepare('select name from employee where salary > 10000'); $command->execute(); $data = $command->fetchAll(PDO::FETCH_ASSOC); /* $data = array ( 0 => array ( 'name' => 'Mike', ), 1 => array ( 'name' => 'Tom', ), 2 => array ( 'name' => 'Jerry', ), 3 => array ( 'name' => 'Mary', ) ); */ $names = new ArrayHandler($data); $result = $names->simplify(); echo var_export($result,true); /* LanguageSpecific\ArrayHandler::__set_state(array( '_data' => array ( 0 => 'Mike', 1 => 'Tom', 2 => 'Jerry', 3 => 'Mary', ), )) */ 

当然,您可以遍历将从请求返回的数组,并进行以下分配:

 $response[] = $element[0]; 

,但我不太喜欢它,让它自动发生,于是出现了simple ()方法。

好吧,因为我们在数组上有包装器,所以我们将添加一个方法来检查索引的存在-has(),如果要遍历数组的元素,则next ()方法会有所帮助。

由于自动化级别达到了一个舒适的水平,这可能已经停止了,但是有时我必须使用嵌套数组的嵌套数组,对于我来说,立即获取目标数组的ArrayHandler更为方便,因此我添加了pull ()方法,该方法为嵌套数组返回ArrayHandler

看起来像这样:

 $address = new ArrayHandler($item)->pull('metaDataProperty')->pull('GeocoderMetaData')->pull('Address')->asIs(); 

您当然可以这样写:

 $address = $item['GeoObject']['metaDataProperty']['GeocoderMetaData']['Address']; 

,但是在我的眼中,方括号的数量不尽相同,通过pull ()对我来说更方便。

一般推理


当从Composer连接代码时,它非常方便,除了摆脱了复制粘贴的需要之外,您只需一个命令即可获得库,并且它始终可用。

在制作程序包之前,我研究了类似物,但没有找到类似的东西,有几个项目只包装在一个数组上,而在这些项目中,它们只是包装了许多处理数组的方法,并且在任何地方都没有类型安全性。

显然,对每个人来说,在变量名前写(int)或(bool)都是简单而方便的,而且没有人发现有任何理由为此事而烦恼使用单独的存储库。

库功能比本文中描述的功能略宽,可以在文档(README.md)中获得更多信息。

PHP5并不少见,因此该库为PHP5提供了一个单独的版本,与PHP7的版本在几种方法的名称上有所不同,当然,所有类型提示仅在注释中。
PHP7.2有一个版本的库,它的不同之处仅在于返回值的类型出现在object ()方法的签名-object中。

测试完全覆盖了该代码,但是原则上没有什么坏处:)

为了健康!

另一个用例


 foreach ($featureMember as $item) { $pointInfo = extract($item); $info = new ArrayHandler($pointInfo); $address = $info->get('formatted')->default('')->str(); $longitude = $info->get('longitude')->default(61.402554)->double(); $latitude = $info->get('latitude')->default(55.159897)->double(); $undefined = !$info->get('formatted')->has(); $properties = ['longitude' => $longitude, 'latitude' => $latitude, 'address ' => $address ,'undefined'=>$undefined,]; $result = json_encode($properties); output($result); } 

在对JSON进行调试时(其中数字是数字,逻辑值是逻辑),我比字符串更令人愉悦。

图片

那你呢

Source: https://habr.com/ru/post/zh-CN476102/


All Articles