那些糟糕的 PHP 代码
摘录自: 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("&", "&amp;", $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 --