三元运算和if语句。
我先道歉,我最近才发现我用的wamp不是我说的那一版,我安装wamp的时候没删老版的,而且安装在了原目录。现在发现新版的默认配置是如果变量未赋初值,就会报错。虽然变量未赋初值改配置文件就可以,这样写起来也方便,但据我的经验,这样做,好处比坏处少。
现在在下面的二段代码中加入了这两句,就不会报错了。
isset($_POST['user_id']) ? '' : $_POST['user_id'] = '';
isset($_POST['user_name']) ? '' : $_POST['user_name'] = '';
下面的例子有sql注入漏洞。另外,如果输入内容中含有双引号,也会破坏表单。
这个是三元运算的例子,注意下面的html代码中有php代码。
<!-- ternary.php start -->
<?php
isset($_POST['user_id']) OR $_POST['user_id'] = FALSE;
isset($_POST['user_name']) OR $_POST['user_name'] = FALSE;
$sql_where = ($_POST['user_id'] != '' ? " and b='{$_POST['user_id']}'" : '') .
($_POST['user_name'] != '' ? " and b='${_POST['user_name']}'" : '');
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
</head>
<body>
<form method="post" accept-charset="utf-8" >
<?php echo ($sql_where !== '' ? ' where ' . substr($sql_where, 4) : ''); ?>
<br/>
<input type="text" name="user_id" id="user_id" value="" maxlength="100" size="50" style="width:50%" />
<input type="text" name="user_name" id="user_name" value="<?php echo $_POST['user_name']; ?>" maxlength="100" size="50" style="width:50%" />
<input type="submit" name="mysubmit" value="Submit Post!" />
</form>
</body>
</html>
<!-- ternary.php end -->
用if语句要麻烦一些。
<!-- if.php start -->
<?php
$sql_where = '';
isset($_POST['user_id']) OR $_POST['user_id'] = FALSE;
isset($_POST['user_name']) OR $_POST['user_name'] = FALSE;
if ($_POST['user_id'] != '')
{
$sql_where .= " and b='{$_POST['user_id']}'";
}
if ($_POST['user_name'] != '')
{
$sql_where .= " and b='${_POST['user_name']}'";
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
</head>
<body>
<form method="post" accept-charset="utf-8" >
<?php if ($sql_where !== ''){ echo ' where ' . substr($sql_where, 4); } ?>
<br/>
<input type="text" name="user_id" id="user_id" value="" maxlength="100" size="50" style="width:50%" />
<input type="text" name="user_name" id="user_name" value="<?php echo $_POST['user_name']; ?>" maxlength="100" size="50" style="width:50%" />
<input type="submit" name="mysubmit" value="Submit Post!" />
</form>
</body>
</html>
<!-- if.php end -->
但是,很多时候用if或switch语句更好, 还可以用数组的键值代替(参见《代码大全》这本书)。而用三元运算符很多时候会让代码不合规范, 不易理解。(在php5.4之前,三元运算符相比if语句,效率较低,5.4之后就差不多了,详见这篇博客 http://www.laruence.com/2011/11/04/2258.html)
<?php
/* phpnet dot 20 dot dpnsubs at xoxy dot net (01-Nov-2007 10:13) */
$a = 2;
echo ($a === 1 ? 'one' :
($a === 2 ? 'two' :
($a === 3 ? 'three' :
($a === 4 ? 'four' : 'other'))));
echo '<br/>';
//很像lisp的if语句
/* ;lisp
(setq b 3)
(print (if (equal b 1)
"one"
(if (equal b 2)
"two"
(if (equal b 3)
"three")))) */
$b = 3;
if ($b === 1)
{
echo 'one';
}
elseif ($b === 2)
{
echo 'two';
}
else if ($b === 3)
{
echo 'three';
}
echo '<br/>';
$c = 1;
switch ($c)
{
case 1:
echo 'one';
break;
case 2:
echo 'two';
break;
}
echo '<br/>';
/* ;lisp
(setq c 2)
(cond ((equal c 1) (print "one"))
((equal c 2) (print "two"))
((equal c 3) (print "three")))
*/
$d = 3;
$e = '1';
$arr_num = array (
1 => 'one',
'2' => 'two',
'3' => 'three',
'11' => 'four',
'nil'
);
echo $arr_num[$d] , '-' , $arr_num[$e] , '-' , $arr_num[12];
echo '<br/>';
//很明显,用数组,条件和方法更好分离。
/* ;lisp
(setf a 3)
(setf trans '((1 . "one")
(2 . "two")
(3 . "three")
(3 . "three2")))
(print (cdr (assoc 'a trans))) */
?>
基于数组对if语句的重构。
用if时。
<?php
$table = 'test_order';
if ($table === 'test_order' OR
$table === 'test_client' OR
$table === 'test_area')
{
echo $table;
}
else
{
die('err');
}
?>
用数组代替多个OR时。
<?php
$table = 'test_order';
$arr = array(
'test_order' => '',
'test_area' => '',
'test_client' => '',);
if (isset($arr[$table]))
{
echo $table;
}
else
{
die('err');
}
?>
很明显用数组代码更少,更重要的是,数据可以作为值来传递,而在php中,代码是不能作为数据结构来传递的。当然,有时候用数组会损失一点点效率,但不是系统瓶颈的话,是不值得去优化的——过早优化之所以不好,是因为很多时候优化 约等于 “写死”, 也就失去了灵活性。
基于switch和函数对if语句的重构。
<?php
$inkai_pattern = '3';
$dly_summary = 123;
$dly_sum_nyukai = 55;
$dly_nyu_keskin2 = 1;
$dly_nyu_keskin3 = 2;
$dly_nyu_keskin4 = 4;
$dly_nyu_keskin5 = 8;
$dly_nyu_keskin6 = 16;
$dly_dpe_urikin = 13;
$dly_bup_urikin = 14;
//重构前的代码——先辈的代码 变量都是些日语拼音,不过我们单位多数的表都是日语拼音命名的。
if ($inkai_pattern == "1")
{
$dly_nyu_genkin = $dly_summary - ($dly_nyu_keskin2 + $dly_nyu_keskin3 + $dly_nyu_keskin4 + $dly_nyu_keskin5 + $dly_nyu_keskin6);
$dly_tenant_kin = 0;
}
elseif ($inkai_pattern == "2")
{
$dly_nyu_genkin = 0;
$dly_tenant_kin = $dly_summary - ($dly_nyu_keskin2 + $dly_nyu_keskin3 + $dly_nyu_keskin4 + $dly_nyu_keskin5 + $dly_nyu_keskin6);
}
elseif ($inkai_pattern == "3")
{
$dly_nyu_genkin = $dly_sum_nyukai + $dly_dpe_urikin + $dly_bup_urikin;
$dly_tenant_kin = $dly_summary - $dly_nyu_genkin - ($dly_nyu_keskin2 + $dly_nyu_keskin3 + $dly_nyu_keskin4 + $dly_nyu_keskin5 + $dly_nyu_keskin6);
}
elseif ($inkai_pattern == "4")
{
$dly_nyu_genkin = $dly_sum_nyukai + $dly_bup_urikin;
$dly_tenant_kin = $dly_summary - $dly_nyu_genkin - ($dly_nyu_keskin2 + $dly_nyu_keskin3 + $dly_nyu_keskin4 + $dly_nyu_keskin5 + $dly_nyu_keskin6);
}
elseif ($inkai_pattern == "5")
{
$dly_nyu_genkin = $dly_sum_nyukai;
$dly_tenant_kin = $dly_summary - $dly_nyu_genkin - ($dly_nyu_keskin2 + $dly_nyu_keskin3 + $dly_nyu_keskin4 + $dly_nyu_keskin5 + $dly_nyu_keskin6);
}
elseif ($inkai_pattern == "6")
{
$dly_nyu_genkin = $dly_sum_nyukai;
$dly_tenant_kin = $dly_summary - $dly_nyu_genkin - ($dly_nyu_keskin2 + $dly_nyu_keskin3 + $dly_nyu_keskin4 + $dly_nyu_keskin5 + $dly_nyu_keskin6);
}
var_dump($dly_nyu_genkin, $dly_tenant_kin);
// 重构后的代码
list($dly_nyu_genkin, $dly_tenant_kin) = get_cash_deposit($inkai_pattern, array(
'all_summary' => $dly_summary,
'all_sum_nyukai' => $dly_sum_nyukai,
'bup_urikin' => $dly_dpe_urikin,
'dpe_urikin' => $dly_bup_urikin,
'nyu_keskin2' => $dly_nyu_keskin2,
'nyu_keskin3' => $dly_nyu_keskin3,
'nyu_keskin4' => $dly_nyu_keskin4,
'nyu_keskin5' => $dly_nyu_keskin5,
'nyu_keskin6' => $dly_nyu_keskin6,
));
var_dump($dly_nyu_genkin, $dly_tenant_kin);
function get_cash_deposit($inkai_pattern, $data)
{
//对未定义的值设定默认值, 如果必须有值,则不应设默认值。
$data = array_merge(
array(
'bup_urikin' => 0,
'dpe_urikin' => 0,
), $data
);
$data['_pattern'] = (int) $inkai_pattern;
{// 很旧的项目配置register_globals = on ,不可以用extract,所以以后做新项目一定要把这个关了。实际上下面的写法很傻,可以用很简单的写法代替extract函数。
/* $all_summary = $data['all_summary'];
$all_sum_nyukai = $data['all_sum_nyukai'];
$bup_urikin = $data['bup_urikin'];
$dpe_urikin = $data['dpe_urikin'];
$nyu_keskin2 = $data['nyu_keskin2'];
$nyu_keskin3 = $data['nyu_keskin3'];
$nyu_keskin4 = $data['nyu_keskin4'];
$nyu_keskin5 = $data['nyu_keskin5'];
$nyu_keskin6 = $data['nyu_keskin6'];
$_pattern = $data['_pattern']; */
//觉得自己傻了,实际上可以用一个循环代替extract
foreach ($data as $key=>$val)
{${$key} = $val;
}
}
$sum_nyu_keskin = $nyu_keskin2 + $nyu_keskin3 + $nyu_keskin4 + $nyu_keskin5 + $nyu_keskin6;
$nik_data = 0;
$tenant_kin = 0;
switch ($_pattern)
{
case 1:
$nik_data = $all_summary - $sum_nyu_keskin;
$tenant_kin = 0;
break;
case 2:
$nik_data = 0;
$tenant_kin = $all_summary - $sum_nyu_keskin;
break;
case 3:
$nik_data = $all_sum_nyukai + $bup_urikin + $dpe_urikin;
$_pattern = 101;
continue;
case 4:
$nik_data = $all_sum_nyukai + $bup_urikin;
$_pattern = 101;
continue;
case 5:
case 6:
$nik_data = $all_sum_nyukai;
$_pattern = 101;
continue;
case 101:
$tenant_kin = $all_sum_nyukai - $nik_data - $sum_nyu_keskin;
break;
}
return array($nik_data, $tenant_kin);
}
?>
很明显用数组代码更少,更重要的是,数据可以作为值来传递,而在php中,代码是不能作为数据结构来传递的。当然,有时候用数组会损失一点点效率,但不是系统瓶颈的话,是不值得去优化的——有时候优化之所以不好,是因为很多时候优化 约等于 “写死”, 也就失去了灵活性。
php手册中switch这一章讲了很多细节,大家可以看下。
由于这一章代码多一些,希望刚刚学编程的人就不要用记事本了。建议用nopepad++或PSPad做文本编辑器,然后从易到难,再学习vi。IDE会有一些很有用的提示(偶尔会打扰思路,但对初学者非常有用),个人推荐NetBeans这个集成环境做开发。