assert()和eval()
assert():
assert这个函数在php语言中是用来判断一个表达式是否成立。返回true or false;
例如
<?php $s = 123; assert("is_int($s)"); ?>
从这个例子可以看到字符串参数会被执行,这跟eval()类似。不过eval($code_str)只是执行符合php编码规范的$code_str。assert的用法却更详细一点。
assert_option()可以用来对assert()进行一些约束和控制;
默认值
ASSERT_ACTIVE=1 //Assert函数的开关
ASSERT_WARNING =1 //当表达式为false时,是否要输出警告性的错误提示,issue a PHP warning for each failed assertion
ASSERT_BAIL= 0 //是否要中止运行;terminate execution on failed assertions
ASSERT_QUIET_EVAL= 0 //是否关闭错误提示,在执行表达式时;disable error_reporting during assertion expression evaluation
ASSERT_CALLBACK= (NULL) // 是否启动回调函数 user function to call on failed assertions
如果按照默认值来,在程序的运行过程中调用assert()来进行判断表达式,遇到false时程序也是会继续执行的,这在生产环境中这样使用是不好的,而 在开发调试环境中,却是一种debug的不错的方式。特别是用上callback的方法,可以知道具体的出错信息。例如
1 <?php 2 // Active assert and make it quiet 3 assert_options(ASSERT_ACTIVE, 1); 4 assert_options(ASSERT_WARNING, 0); 5 assert_options(ASSERT_QUIET_EVAL, 1); 6 7 // Create a handler function 8 function my_assert_handler($file, $line, $code) 9 { 10 echo "<hr>Assertion Failed:File '$file'<br /> 11 Line '$line'<br /> 12 Code '$code'<br /><hr />"; 13 } 14 15 // Set up the callback 16 assert_options(ASSERT_CALLBACK, 'my_assert_handler'); 17 18 // Make an assertion that should fail 19 assert('mysql_query("")'); 20 ?>
所以,php的官方文档里头是建议将assert用来进行debug,我们可以发现还有一个开关ASSERT_ACTIVE可以用来控制是否开启debug。
现在问题就产生了,如果程序员在开发的时候在代码中留下了很多assert(),然后在程序发布的时候关闭执行,设置assert_options(ASSERT_ACTIVE,0);这样做是否可行?有没有安全问题?
我的建议是,既然assert主要作用是debug,就不要在程序发布的时候还留着它。在程序中用assert来对表达进行判断是不明智的,原因上文说了, 一个是在生产环境中assert可能被disabled,所以assert不能被完全信任;二是assert()可以被继续执行;而如果在生产环境让ASSERT_ACTIVE=1,那这个表达式字符串可以被执行本身就存在安全隐患。
例如
<?php function fo(){ $fp = fopen("c:/test.php",'w'); fwrite($fp,"123"); fclose($fp); return true; } assert("fo()"); ?>
eval():该函数对于在数据库文本字段中供日后计算而进行的代码存储很有用。
<?php $name = "zhangsan"; $str = "He is $name"; $d = eval("return \$str;"); var_dump($d); ?>
注意:1.eval()里必须是字符串;2.eval()里的引号必须是双引号,因为单引号不能解析字符串里的变量$str;
定义和用法:
(1)eval() 函数把字符串按照 PHP 代码来计算(计算=执行)。
(2)该字符串必须是合法的 PHP 代码,且必须以分号结尾。
(3)如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。