Cách tốt hơn để kiểm tra biến cho null hoặc chuỗi rỗng?


174

Vì PHP là một ngôn ngữ động, cách kiểm tra tốt nhất để xem trường được cung cấp có trống không?

Tôi muốn đảm bảo rằng:

  1. null được coi là một chuỗi rỗng
  2. một chuỗi chỉ khoảng trắng được coi là trống
  3. rằng "0" không được coi là trống

Đây là những gì tôi đã có cho đến nay:

$question = trim($_POST['question']);

if ("" === "$question") {
    // Handle error here
}

Phải có một cách đơn giản hơn để làm điều này?


1
Tôi sẽ nói sử dụng khoảng trống (câu hỏi $), nhưng điều đó cũng coi 0 là trống.
Powerlord

2
điều kiện yoda thật tồi tệ
dùng3791372

Câu trả lời:


278
// Function for basic field validation (present and neither empty nor only white space
function IsNullOrEmptyString($str){
    return (!isset($str) || trim($str) === '');
}

7
Mặc dù điều này giải quyết nó, tôi không chắc nó đơn giản hơn. +1 dù sao
Allain Lalonde

4
Vì OP đang yêu cầu một phiên bản 'đơn giản hơn' của một hoạt động cực kỳ đơn giản, tôi sẽ nói rằng 'tốt hơn' là những gì thực sự được bảo hành.
hỗn loạn

2
Tôi đã biến nó thành một chức năng. điều này sẽ làm cho mã xác thực của bạn đơn giản hơn
Michael Haren

7
mục đích của! isset () ở đây là gì? Nó khác với is_null () như thế nào?
nickf

2
cũng trả về (! trống ($ câu hỏi) | | trim ($ câu hỏi) === '');
SpYk3HH

109

Bài cũ nhưng ai đó có thể cần nó như tôi đã làm;)

if (strlen($str) == 0){
do what ever
}

thay thế $strbằng biến của bạn. NULL""cả hai trả về 0 khi sử dụng strlen.


4
Và luôn luôn có:if(strcmp('', $var) == 0)...
peter

12
Tại sao == 0 và không chỉ if (strlen ($ str))?
Noumenon

14
@Noumenon Vì điều đó sẽ làm giảm khả năng đọc mà không giải quyết được gì. Thật dễ dàng để đọc đề xuất của bạn là "nếu có độ dài" trong khi nó (tất nhiên) có nghĩa ngược lại.
Mattias Åslund

10
Sẽ không giúp cho chuỗi chỉ có khoảng trắng, nếu ai đó quan tâm đến điều đó
airboss

4
Nếu biến không được đặt, điều này sẽ tạo ra cảnh báo
Konstantin Pereiaslov

26

Sử dụng hàm rỗng () của PHP. Những điều sau đây được coi là trống rỗng

"" (an empty string)
0 (0 as an integer)
0.0 (0 as a float)
"0" (0 as a string)
NULL
FALSE
array() (an empty array)
$var; (a variable declared, but without a value)

Để biết thêm chi tiết kiểm tra chức năng trống


6
Poster nói rằng họ KHÔNG muốn xem xét "0" trống
dougd_in_nc

19

Tôi sẽ khiêm tốn chấp nhận nếu tôi sai, nhưng tôi đã tự mình kiểm tra và thấy rằng các công việc sau đây để kiểm tra cả hai biến có giá trị chuỗi (0) "" và NULL:

if ( $question ) {
  // Handle success here
}

Điều này cũng có thể được đảo ngược để kiểm tra thành công như vậy:

if ( !$question ) {
  // Handle error here
}

Tôi có thể đề xuất "if (trim ($ n)) .." nếu không, nếu $ _POST var (ví dụ) chỉ đơn giản là "", thì nó sẽ được coi là hợp lệ, trong khi, trong hầu hết các trường hợp, điều này tốt như một chuỗi rỗng
StartupGuy

Nếu "" không phải là giá trị chấp nhận được cho một chức năng cụ thể, thì sử dụng trim sẽ là một ý tưởng tuyệt vời.
Adal

2
Điều này sẽ trả về false cho "0", số 0 hoặc 0,0 và FALSE.
Vedmant

7

Coi chừng các phủ định sai từ trim()hàm - nó thực hiện chuyển đổi chuỗi trước khi cắt, và do đó sẽ trả về ví dụ "Mảng" nếu bạn truyền cho nó một mảng trống. Đó có thể không phải là vấn đề, tùy thuộc vào cách bạn xử lý dữ liệu của mình, nhưng với mã bạn cung cấp, một trường có tên question[]có thể được cung cấp trong dữ liệu POST và dường như là một chuỗi không trống. Thay vào đó, tôi sẽ đề nghị:

$question = $_POST['question'];

if (!is_string || ($question = trim($question))) {
    // Handle error here
}

// If $question was a string, it will have been trimmed by this point

Id nói nếu bạn nhận được một mảng mà bạn mong đợi một chuỗi thì đó sẽ là một lỗi. Nếu bạn mong đợi một mảng thì bạn nên có một chức năng lọc riêng cho điều đó.
OIS

Không phải mã đó coi nó là một lỗi sao? Nếu quá trình lọc được thực hiện ở nơi khác, cần lưu ý rằng đó không phải là sao chép kiến ​​thức về các quy tắc xác thực của đối số vào các vị trí riêng biệt.
Grantwparks

3

Không có cách nào tốt hơn nhưng vì đó là một hoạt động bạn thường làm khá thường xuyên, nên bạn sẽ tự động hóa quy trình tốt hơn.

Hầu hết các khung công tác cung cấp một cách để làm cho các đối số phân tích cú pháp một nhiệm vụ dễ dàng. Bạn có thể xây dựng đối tượng của riêng bạn cho điều đó. Ví dụ nhanh và bẩn:

class Request
{

    // This is the spirit but you may want to make that cleaner :-)
    function get($key, $default=null, $from=null)
    {
         if ($from) :
             if (isset(${'_'.$from}[$key]));
                return sanitize(${'_'.strtoupper($from)}[$key]); // didn't test that but it should work
         else
             if isset($_REQUEST[$key])
                return sanitize($_REQUEST[$key]);

         return $default;
    }

    // basics. Enforce it with filters according to your needs
    function sanitize($data)
    {
          return addslashes(trim($data));
    }

    // your rules here
    function isEmptyString($data)
    {
        return (trim($data) === "" or $data === null);
    }


    function exists($key) {}

    function setFlash($name, $value) {}

    [...]

}

$request = new Request();
$question= $request->get('question', '', 'post');
print $request->isEmptyString($question);

Symfony sử dụng loại đường đó một cách ồ ạt.

Nhưng bạn đang nói về nhiều hơn thế, với "// Xử lý lỗi ở đây". Bạn đang trộn 2 công việc: lấy dữ liệu và xử lý nó. Điều này không giống nhau chút nào.

Có các cơ chế khác bạn có thể sử dụng để xác nhận dữ liệu. Một lần nữa, các khung có thể cho bạn thấy những điều tốt nhất.

Tạo các đối tượng đại diện cho dữ liệu của biểu mẫu của bạn, sau đó đính kèm các quy trình và quay lại với nó. Nghe có vẻ nhiều việc hơn khi hack một đoạn mã PHP nhanh (và đây là lần đầu tiên), nhưng nó có thể tái sử dụng, linh hoạt và ít bị lỗi hơn do xác thực mẫu với PHP thông thường có xu hướng nhanh chóng trở thành mã spaguetti.


21
Bạn đã làm ngược lại chính xác những gì anh ấy muốn ... đơn giản.
TravisO

2

Cái này kiểm tra mảng chuỗi:

function is_set($val) {
  if(is_array($val)) return !empty($val);

  return strlen(trim($val)) ? true : false;
}

Không tệ. Câu trả lời của PHPst cũng làm như vậy nhưng chính xác hơn.
Allain Lalonde

2

để mạnh mẽ hơn (lập bảng, trả lại), tôi xác định:

function is_not_empty_string($str) {
    if (is_string($str) && trim($str, " \t\n\r\0") !== '')
        return true;
    else
        return false;
}

// code to test
$values = array(false, true, null, 'abc', '23', 23, '23.5', 23.5, '', ' ', '0', 0);
foreach ($values as $value) {
    var_export($value);
    if (is_not_empty_string($value)) 
        print(" is a none empty string!\n");
    else
        print(" is not a string or is an empty string\n");
}

nguồn:


1

Khi bạn muốn kiểm tra xem một giá trị được cung cấp cho một trường, trường đó có thể là một string, một arrayhoặc không xác định. Vì vậy, sau đây là đủ

function isSet($param)
{
    return (is_array($param) && count($param)) || trim($param) !== '';
}

0

blank () được sử dụng để làm việc này, nhưng hành vi của void () đã thay đổi nhiều lần. Như mọi khi, các tài liệu php luôn là nguồn tốt nhất cho hành vi chính xác và các nhận xét trên các trang đó thường cung cấp một lịch sử tốt về các thay đổi theo thời gian. Nếu bạn muốn kiểm tra thiếu thuộc tính đối tượng, một phương pháp rất phòng thủ tại thời điểm này là:

if (is_object($theObject) && (count(get_object_vars($theObject)) > 0)) {
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.