iT邦幫忙

1

PHP變數宣告技巧?switch ($_GET[]) 報錯問題?

com 2019-10-20 10:12:152190 瀏覽

每次我都會在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的新寫法。
想知道各種處理這類情況大家的方案,希望還能收集多一點,再撐一下選答喔!(最佳解答為何不能複選?)

5
Samと可樂快跑
iT邦研究生 2 級 ‧ 2019-10-20 15:57:03
最佳解答
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');

如果程式碼有錯或不能執行很正常……因為我沒有實際跑過。
邊忙邊隨便寫出來的東西。

1
小魚
iT邦大師 1 級 ‧ 2019-10-20 10:25:04

使用像Laravel之類的框架,
他會幫你處理很多東西,
如果要自己寫的話等你成為高手之後再來寫吧.

2
淺水員
iT邦新手 2 級 ‧ 2019-10-20 11:35:12

這樣呢?

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);

我猜你應該幫新手說明一下 &$arr 的意思 XD

0
浩瀚星空
iT邦大師 1 級 ‧ 2019-10-21 00:48:11

本來要寫物件的方式,沒想到已經由叔叔寫完了。

其實從php7之後,已經很多人碰到很多警告等級的問題。
原因其實也不過就是php7將以前某些弱型寫法通融過去的地方,給他寫嚴格了。

認真來說,現在程式的寫法,也盡量不要直接用get、post值了。
在安全性上最好還是寫過input類來處理。
這樣子也可以順便處理你的問題。

小魚會告訴你用Laravel。就是要使用它的現成的input類處理方式。
如果不想要用框架而要自已處理的話。那你就需要有物件的觀念。
一定不可能用簡單的幾行就可以搞定你的問題。

0
jellyalex978
iT邦新手 5 級 ‧ 2019-10-21 04:55:49

既然是初學 還是要強調幾個重點

  1. 變數本來就應該要宣告好 XD
    寫 php 是可以很懶惰沒錯 , 但未來你碰到 java , c , ++ 就會慢慢理解
    其實變數先宣告好非常的重要 , 盡量不偷懶

  2. 如問題範例中 , 一次 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 沒開編輯器隨便打得 , 有錯自己修一下

2
ppc52776
iT邦新手 5 級 ‧ 2019-10-21 09:56:48

使用 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) {}

0
程式狗
iT邦新手 4 級 ‧ 2019-10-21 10:24:54

不管有沒有使用framework該有的判斷都還是要有,比如你的狀況isset()一定得使用,假設為了改善這個狀況而使用framework,不過也是使用framework包裝好的object或function,該有的判斷一樣存在,當然包含類似於isset()的判斷,優點是程式碼會較簡潔、乾淨,且例外處理得更完善,速度效能就算有差異也是程式經驗所造成而不是isset()造成的。

再來是isset()大量使用效率會變差這點抱持著些疑問,isset()在php裡屬於一種語言結構要使用isset()到嚴重拖垮執行效率,總歸來說是程式寫法有問題。

0
Dion
iT邦新手 5 級 ‧ 2019-10-21 23:42:06

使用framework也要知道,到底多少東西他幫忙處理。
知道她處理的甚麼怎麼處理,這樣未來遇到風險發生時,才知道如何修補。
直接使用GET/POST真的是很不建議這樣做。

其實就是變數使用前都要先宣告的習慣養成,這樣未來開發上也會有助說明除錯。

我要發表回答

立即登入回答