2010-08-24 28 views
6

Là một nhà phát triển web, tôi luôn sử dụng phương pháp này để một cái gì đó giống như một mẫu đăng nhập hoặc khác “lưu” hoạt động (bỏ qua sự nguy hiểm của việc truy cập trực tiếp các biến đầu vào):Có cách nào để truy cập tự động siêu siêu dữ liệu không?

if (isset($_POST['action']) && $_POST['action'] == 'login') 
{ 
    // we're probably logging in, so let's process that here 
} 

Để làm điều này ít tẻ nhạt và giữ phù hợp với nguyên tắc DRY (loại), tôi nấu này lên:

function isset_and_is ($superglobal, $key, $value) 
{ 
    $ref = '_' . strtoupper($superglobal); 

    return isset($$ref[$key]) && $$ref[$key] == $value; 
} 

if (isset_and_is('post', 'action', 'login')) 
{ 
    // we're probably logging in, so let's process that here 
} 

này thất bại thảm hại, mặc dù sử dụng oh-so-thông minh của tôi về tên biến động để truy cập superglobal.

Vì vậy, tôi đang mắc kẹt sử dụng xấu xí này:

function isset_and_is ($superglobal, $key, $value) 
{ 
    switch (strtoupper($superglobal)) 
    { 
     case 'GET':  $ref =& $_GET;  break; 
     case 'POST': $ref =& $_POST; break; 
     case 'REQUEST': $ref =& $_REQUEST; break; 
     default:  die('megafail'); return; 
    } 

    return isset($ref[$key]) && $ref[$key] == $value; 
} 

if (isset_and_is('post', 'action', 'login')) 
{ 
    // we're probably logging in, so let's process that here 
} 

Câu hỏi của tôi: Có cách nào để truy cập tự động các biến superglobal như tôi đang cố gắng làm trong mẫu mã thứ hai của tôi? Nếu không, có cách nào tốt hơn/hiệu quả hơn để hoàn thành những gì tôi đang làm trong mẫu mã thứ ba không?


Giải pháp của tôi: Nhờ Tom Haigh's answer, đây là mã cuối cùng tôi sẽ đi với:

function isset_and_is ($superglobal, $key, $value) 
{ 
    $ref =& $GLOBALS['_' . strtoupper($superglobal)]; 

    return isset($ref[$key]) && $ref[$key] == $value; 
} 
+1

Và điều gì sai với mẫu đầu tiên? – NullUserException

+0

NullUserException: DRY :) –

+1

IMO mẫu đầu tiên rõ ràng hơn, DRYer và dễ dàng cho bất kỳ ai biết PHP hiểu. Trong khi những cái khác ... – NullUserException

Trả lời

3

Bạn có thể làm điều đó như thế này:

function test($var) { 
    //this 
    var_dump($GLOBALS[$var]); 

    //or this 
    global $$var; //this is needed even for superglobals 
    var_dump($$var); 
} 

test('_GET'); 

vì vậy bạn có thể sử dụng nội dung như thế này trong trường hợp của bạn

function isset_and_is ($superglobal, $key, $value) { 
    $var = '_' . $superglobal; 
    return isset($GLOBALS[$var]) && ($GLOBALS[$var][$key] == $value); 
} 

$is_login = isset_and_is('GET', 'action', 'login'); 

Hoặc cách khác bạn có thể lấy biến theo tham chiếu và sử dụng isset(), ví dụ:

function get_var(& $var) { 
    if (isset($var)) { 
     return $var; 
    } 
    return null; 
} 

//will not give you a notice if not set 
$post_var = get_var($_POST['var']); 

if (get_var($_GET['action']) == 'login') { 
    //stuff 
} 
-1

Khi $_REQUEST theo mặc định chứa các nội dung của $_GET$_POST, tại sao bạn cần chuyển đổi hợp cụ thể. Bạn có thể trực tiếp sử dụng này và loại bỏ $superglobal:

function isset_and_is ($key, $value) 
{ 
    return isset($_REQUEST[$key]) && ($_REQUEST[$key] == $value); 
} 
+0

'$ _REQUEST' không an toàn nếu tôi chỉ muốn cho phép thông tin đăng nhập qua' POST', ví dụ: –

1

Làm thế nào về: http://www.php.net/manual/en/function.filter-input.php

function isset_and_is ($superglobal, $key, $value) { 
    switch($superglobal) { 
    case 'post': 
     $type = INPUT_POST; 
     break; 
    case 'get': 
     $type = INPUT_GET; 
     break; 
    } 
    $var = filter_input($type,$key); 
    if(is_null($var)) return false; 
    return($var == $value); 
} 
+0

Câu trả lời của bạn hoàn toàn bỏ qua câu hỏi, và chỉ đơn giản là cung cấp một giải pháp crufty bằng nhau cho mẫu mã thứ ba của tôi. –

+1

Thành thật mà nói, tôi không thể thấy nó bỏ qua câu hỏi của bạn như thế nào. Do bạn thực sự có thể sử dụng các hằng số INPUT_ * làm đối số cho hàm này để loại bỏ công tắc, nó trở thành một giải pháp thực sự tốt đẹp IMHO. – Mchl

2

Nếu bạn cần lấy chỉ từ một nguồn, đi với Tom answer.

Tuy nhiên, nếu bạn làm điều này cho mọi biến, tức là nếu bạn luôn thừa nhận rằng dữ liệu có thể đến từ hai nguồn, cách tốt nhất là hợp nhất chúng.

Bạn có thể sử dụng $_REQUEST, nhưng tôi khuyên bạn nên chống lại nó. Thứ tự xem xét dữ liệu POST và GET là php.ini có thể định cấu hình và nó bao gồm các nguồn khác.

làm cái gì đó như:

$data = array_merge($_GET, $_POST); //POST has precedence 

và sau đó nhận được dữ liệu của bạn từ $data.

+0

Không được ưu tiên ở đây? Ý tôi là, nếu '$ _POST ['var']' và '$ _GET ['var']' được thiết lập, nó sẽ chọn '$ _GET ['var']' – NullUserException

+0

Tôi không thừa nhận dữ liệu luôn có thể đến từ hai nguồn; ngược lại, dữ liệu sẽ chỉ xuất phát từ một trong các siêu dữ liệu, tùy thuộc vào nơi tôi truy cập dữ liệu đó. Nhưng, tôi muốn có thể sử dụng lại chức năng này. –

+0

@Null Rất tiếc, bạn đã đúng. Đã sửa. – Artefacto

0

Trong PHP, toán tử @ ngăn chặn cảnh báo trong khi đánh giá biểu thức. Ví dụ: $array[$key] trả về giá trị bằng khóa đó nếu nó tồn tại hoặc null nếu không, nhưng sẽ tăng cảnh báo nếu khóa không tồn tại. Thêm nhà điều hành @ để sản xuất @$array[$key] làm cho nó tương đương với array_key_exists($key, $array) ? $array[$key] : null. Trong thực tế, isset($something) chỉ là một cách khác để nói @$something === null.

Vì vậy, cố gắng này:

if (@$_POST['action'] === 'login') 
{ 
    // we're probably logging in, so let's process that here 
} 

dự án PHP của tôi sử dụng một cái gì đó tương tự như đoạn trong documentation of ErrorException. Điều này bổ sung thêm ngữ nghĩa không nhanh, trong đó PHP $array[$key] có nghĩa là ném một số ErrorException nếu nó không có ở đó và @$array[$key] có nghĩa là sử dụng null để không tìm thấy (chẳng hạn như SQL LEFT JOIN).

Các vấn đề liên quan