每次我都會在PHP中將所有【將要】使用到的變數都宣告一遍。
因為要避面後面下面寫法報錯
switch ($_GET['xx1']) {}
switch ($_POST['xx2']) {}
switch ($_GET['xx3']) {}
常常前面宣告變數會有
if(!isset($_GET['xx1'])){$_GET['xx1'] = null;}
if(!isset($_POST['xx2'])){$_POST['xx2'] = null;}
if(!isset($_GET['xx3'])){$_GET['xx3'] = null;}
這些if寫一堆很沒效率,請問各位前輩有沒有甚麼好的寫法,讓可能會$_GET[]或$_POST[]的變數,先處理好?
UPDATE 2019-10-20 10:31
小魚你好:因為在學習基礎面,所以想只針對沒有$GET[]變數時,後面使用到該$GET[]變數而報錯改善寫法,學習基礎時,我想先盡量不要使用框架。
UPDATE 2019-10-21 14:33
感謝淺水員因材施教,謝謝Samと可樂快跑提供物件導向、jellyalex978提供範例、ppc52776的新寫法。
想知道各種處理這類情況大家的方案,希望還能收集多一點,再撐一下選答喔!(最佳解答為何不能複選?)
class Input {
function get($key = null) {
return $this->_input($_GET, $key);
}
function post($key = null) {
return $this->_input($_POST, $key);
}
private function _input($request, $key) {
if ($key == null) {
$results = [];
foreach($request as $key => $value) {
$results[$key] = $this->_input_filter($value);
}
return $results;
}
if (!isset($request[$key])) {
return '';
}
return $this->_input_filter($request[$key]);
}
private function _input_filter($value) {
//這邊就看你要怎麼過濾了。
}
}
用法:
get:
$input = new Input;
$name = $input->get('name');
post:
$input = new Input;
$name = $input->post('name');
如果程式碼有錯或不能執行很正常……因為我沒有實際跑過。
邊忙邊隨便寫出來的東西。
這樣呢?
function initParams(&$arr, $keys, $defaultValue)
{
foreach($keys as $key) {
if(!isset($arr[$key])) {
$arr[$key]=$defaultValue;
}
}
}
//用這個函式將 $_GET['a']、$_GET['b']、$_GET['c'] 給予預設值 null
initParams($_GET, ['a', 'b', 'c'], null);
本來要寫物件的方式,沒想到已經由叔叔寫完了。
其實從php7之後,已經很多人碰到很多警告等級的問題。
原因其實也不過就是php7將以前某些弱型寫法通融過去的地方,給他寫嚴格了。
認真來說,現在程式的寫法,也盡量不要直接用get、post值了。
在安全性上最好還是寫過input類來處理。
這樣子也可以順便處理你的問題。
小魚會告訴你用Laravel。就是要使用它的現成的input類處理方式。
如果不想要用框架而要自已處理的話。那你就需要有物件的觀念。
一定不可能用簡單的幾行就可以搞定你的問題。
既然是初學 還是要強調幾個重點
變數本來就應該要宣告好 XD
寫 php 是可以很懶惰沒錯 , 但未來你碰到 java , c , ++ 就會慢慢理解
其實變數先宣告好非常的重要 , 盡量不偷懶
如問題範例中 , 一次 request 用到 3 個變數 去做 switch
我個人是覺得有一點點怪怪的 , 覺得你把流程變得有點複雜去了
3.還是強調 , 如其他人說的 , 不應該直接使用 $_GET 和 $_POST
最好先處理 , 你可以 google sql injection 看看嚴重度 XD
OK 那再來只討論 怎樣彈性處理變數的問題吧
如果你的變數是流水號 就用 i
如果不是就用 array 存起來
其實可以用變數產生變數
因為你說你初學所以就用基本的回答你
方法 1 , 變數是流水號
for($i=1;$i<=3;$i++){
$_GET['xx'.$i] = (!isset($_GET['xx'.$i]))?null:$_GET['xx'.$i];
}
方法 2 變數不是流水號
$vars = array('aaa','bbb','ccc','ddd');
foreach ($vars as $var) {
$_GET[$var] = (!isset($_GET[$var]))?null:$_GET[$var];
}
這樣可以產生 $aaa0 , $bbb1 , $ccc2 , $ddd3 的變數
$vars = array('aaa','bbb','ccc','ddd');
foreach ($vars as $k => $var) {
${$var.$k} = (!isset($_GET[$var.$k]))?null:$_GET[$var.$k];
}
PS 沒開編輯器隨便打得 , 有錯自己修一下
使用 php7 新增的 Null coalescing operator (null合併運算符號)呢?
由於日常使用中存在大量同時使用三元表達式和 isset()的情況, 我們添加了null合併運算符 (??) 這個語法糖。如果變量存在且值不為NULL, 它就會返回自身的值,否則返回它的第二個操作數。
(來源: https://www.php.net/manual/zh/migration70.new-features.php )
範例:
// 如果 $_GET['user'] 沒有定義, 則返回 null
$username = $_GET['user'] ?? null;
// 此寫法等同於原來 isset 寫法:
$username = isset($_GET['user']) ? $_GET['user'] : null;
// 此寫法也可以串接, 將會返回第一個有定義的值, 如果都沒有定義才會返回最後預設值 null
$username = $_GET['user'] ?? $_POST['user'] ?? null;
樓主提問的 switch 也可寫成:
switch ($_GET['xx1']??null) {}
switch ($_POST['xx2']??null) {}
switch ($_GET['xx3']??null) {}
不管有沒有使用framework該有的判斷都還是要有,比如你的狀況isset()一定得使用,假設為了改善這個狀況而使用framework,不過也是使用framework包裝好的object或function,該有的判斷一樣存在,當然包含類似於isset()的判斷,優點是程式碼會較簡潔、乾淨,且例外處理得更完善,速度效能就算有差異也是程式經驗所造成而不是isset()造成的。
再來是isset()大量使用效率會變差這點抱持著些疑問,isset()在php裡屬於一種語言結構要使用isset()到嚴重拖垮執行效率,總歸來說是程式寫法有問題。
使用framework也要知道,到底多少東西他幫忙處理。
知道她處理的甚麼怎麼處理,這樣未來遇到風險發生時,才知道如何修補。
直接使用GET/POST真的是很不建議這樣做。
其實就是變數使用前都要先宣告的習慣養成,這樣未來開發上也會有助說明除錯。