引见
今朝制止从__toString()抛出异样,并将招致致命谬误。这就使患上挪用恣意代码变患上很风险,并使其成为一个有成绩的通用API。此RFC旨正在勾销此限度。
以后行为的根本原理是,正在整个引擎以及规范库的许多中央都执行了字符串转换,并非一切中央都预备“正确地”解决异样,即尽可能早地解决异样。
从技巧角度来看,这类限度终极是有效的,由于字符串转换时期的异样依然能够由将可规复谬误转换为异样的谬误解决顺序触发:
set_error_handler(function() { throw new Exception(); }); try { (string) new stdClass; } catch (Exception $e) { echo "(string) threw an exception...\n"; }
现实上,Symfony行使这个破绽来绕过以后的限度。可怜的是,这依赖于$errcontext参数,它正在PHP 8中隐没了.
虽然如斯,正在咱们对该代码库中的字符串转换进行了片面审核以前,过来对于该主题的探讨不断不抓紧这类限度。这已正在附加的完成申请中实现。
倡议
容许从__toString()抛出异样,它的行为与往常同样。再也不触发致命谬误。
另外,将“不克不及转换为字符串”以及“__toString()必需前往一个字符串值”可规复的致命谬误转换为正确的谬误异样,这与PHP 7中建设的谬误战略分歧。
扩大原则
想要优雅地解决来自字符串转换的异样的扩大作者,应该思考如下原则:
● 假如zval_get_string()、convert_to_string()以及friends天生一个异样,它们依然会天生一个字符串。这个字符串被保障是暂存的。这象征着不须要开释它,但能够这样做。正在上下文中,您能够抉择更不便的选项。
● 假如从工具到字符串的转换失败,则字符串转换的后果将为空字符串,假如将数组转换为字符串,而且谬误解决顺序将后果告诉晋升为异样,则为“Array”。(这类行为以及之前同样。)
● 通常状况下,应用通常的if (EG(exception))反省来反省能否抛出了异样就足够了:
zend_string *str = zval_get_string(val); if (EG(exception)) { // Possibly free other resources here. return; }
除了此以外,还提供了一些协助api,将转换建模为容易犯错的操作:
// Like zval_get_string() but returns NULL on conversion failure. zend_string *str = zval_try_get_string(val); if (!str) { // Possibly free other resources here. return; } // Main code. zend_string_release(str); // Like zval_get_tmp_string() but returns NULL on conversion failure. zend_string *tmp, *str = zval_try_get_tmp_string(val, &tmp); if (!str) { // Possibly free other resources here. return; } // Main code. zend_tmp_string_release(tmp); // Like convert_to_string() but returns a boolean indicating conversion success/failure. if (!try_convert_to_string(val)) { // Possibly free other resources here. return; } // Main code.
假如转换失败,try_convert_to_string()将没有会修正原始值。因而,应用它比应用convert_to_string()以及异样反省更平安。
尽管反省每个字符串转换一定会使您处于平安的一方,但疏忽这些反省通常只会招致一些不用要的较量争论以及可能的冗余正告。您应该留意的次要事件是修正耐久构造(如数据库)的操作。
没有向后兼容的变卦
从可规复的致命谬误到谬误异样的转换正在技巧上是BC中缀的。
翻译:https://wiki.php.net/rfc/tostring_exceptions
以上就是PHP 7.4容许从 __toString() 抛出异样的具体内容,更多请存眷资源魔其它相干文章!
标签: php7开发教程 php7开发资料 php7开发自学 Php 7.4
抱歉,评论功能暂时关闭!