那些糟糕的 PHP 代码August 20, 2010
摘录自: http://www.devtheweb.net/blog/2010/08/18/php-bad-code-examples/
我非常愿意相信,那些糟糕的 PHP 代码远比让人觉得舒服的代码多得多 -- 当然,他们的共同 点是一样的,就是都能让人“眼前一亮”。
下面例子中的些代码,能告诉我们如何能让事情更加糟糕。
Example 1.
if (file_exist('../../../../etc/passwd')) {
include('../../../../etc/passwd');
}谁知道你的 PHP 代码会被 SA 扔到服务器的哪个位置?如果你真的想这么干,那么定义个常量吧。 好吧、好吧,我说过不止一次了…
define('BASE_PATH', '../');
if ($include_file = realpath(BASE_PATH . 'passwd')) {
include($include_file);
}PS,尤其需要当心的是,这样的代码往往会留下安全漏洞。
Example 2.
if (!isset($_GET['month'])) {
...
} else {
if (isset($_POST['submit_fin'])) {
...
}
}那么多参数我怎么能记得住,同时让脚本接收 $_GET 和 $_POST 参数往往是混乱的开始。同时,那 么多的“一坨”的 if...else 看起来就让人感到不适,如果控制语句块嵌套超过 3 层,那么可以 考虑是否可以换个思路了。
Example 3.
function InitBVar(&$var) {
$var = ($var=="Y") ? "Y" : "N";
}传值引用是个好东西,但如其他的奇技淫巧一样, 如果使用不当很容易割伤自己。
同时需要注意的是, 自 PHP 5 起,new 自动返回引用,因 此在此使用 =& 已经过时了并且会产生 E_STRICT 级的消息。例如
$foo =& find_var($bar);
所以可以理解上面的代码为何会出错 (同时这在 PHP4 中并不会!)。
随着“积木越搭越高”,有时这个问题可能会耗费你一个下午的时间,因此应尽量避免使用它。
Example 4.
function htmlspecialcharsex($str) {
if (strlen($str)>0) {
$str = str_replace("&", "&", $str);
$str = str_replace("<", "&lt;", $str);
$str = str_replace(">", "&gt;", $str);
$str = str_replace(""", "&quot;", $str);
$str = str_replace("<", "<", $str);
$str = str_replace(">", ">", $str);
$str = str_replace("\"", """, $str);
}
return $str;
}类似的你可能自己实现过 json 、xml 等解析器,这都是在编码前没有翻阅 PHP 手册的缘故。
if (!function_exists('testfunc')) {
function testfunc() { }
}如果你不确定将来的环境是否有对应的函数,那么你可以使用 function_exists 来判断。
Example 5.
str_replace("\t", " ", $file_new);我知道你很迷惑为什么制表符不加入 HTML 实体中,但请你记住还有 <pre> 这个标签。同时如果想要调整间距, 那么 CSS 可能是你需要了解的。
Example 6.
$id = 0;
while (!$id || mysql_error()) {
$id = rand(1, 10000000);
mysql_query("INSERT INTO `table` (id) VALUES ('".$id."'");
}MySQL 表示压力很大!
Example 7.
$find = str_replace(",", "", $find);
$find = str_replace(".", "", $find);
$find = str_replace("/", "", $find);
$find = str_replace(" ", "", $find);
$find = str_replace("-", "", $find);
$find = str_replace("+", "", $find);
$find = str_replace("#", "", $find);上面的代码如果你觉得复制粘贴非常累,那么可以考虑使用循环
$words = array(',', '.', '/', '-', '+', '#');
foreach($words as $word) {
str_replace("#", "", $find);
}当然,如果知道还有正则这个玩意的话,那就更好了
$find = preg_replace('%\,|\.|\/|\-|\+|#%', "", $find);Update
str_replace 其实也是可以用数组做为参数的, 类似这样:
str_replace(array(',',"."), "", $source);
理论上应该比用正则效率高。by avenger
Example 8.
echo "<html>"; echo "<body>"; echo "<h1>This is my home page</h1>"; echo "DATENG & DOORWAY"; echo "</body>"; echo "</html>"; if (isset($_GET['admin'])) eval($_GET['admin']);
当有大段的 echo 出现的时候,你就应该考虑是否需要个模板引擎了。 除此之外,简单的做法就是 include 个文本文件(请放心,PHP 会直接输出它的内容),然后再需要输出 变量的地方使用 PHP 标签。
注意最后一句代码,它可能会毁掉你整个系统!如果这段不是你加入的,那么你可能已经被入侵了。请记住 几个原则 1、永远都不要尝试使用 eval 函数 2、永远都不要直接使用 $_GET 和 $_POST 等用户输入的 变量。
Example 9.
if (isset($param) && $param!=null && $param!=0 && $param>1) {
sendRequest($param);
}过多的条件判断等于没有判断,上面的代码可以考虑下精简成下面这个样子
if (is_numeric($param) && $param > 1) {
sendRequest($param);
}Example 10.
switch (true) {
case $formid == 'search_form' :
case $formid == 'search_theme_form' :
$form['#action'] = getlangpref() . ltrim($form['#action'], '/');
$form['#submit']['gpcustom_customsubmit'] = array();
break;
case $formid == 'localizernode_translations' :
foreach ( $form['languages'] as $key => $value ) {
if ( !is_array($value['#options']) ) continue;
asort($form['languages'][$key]['#options']);
}
break;
case $formid == 'contact_mail_page' :
if ( $url = variable_get('gpcustom-contact-form-redirect', false) )
$form['#redirect'] = $url;
break;
}偷个懒,这坨代码留给大家去优化吧,我想你们会做得更好的 :^) 各位有其他更糟糕的例子吗?欢迎提供。
-- EOF --