Tidak dapat menggunakan nilai pengembalian metode dalam konteks tulis

465

Saya pikir potongan kode berikut ini akan berfungsi, tetapi tidak (Diedit: Sekarang berfungsi di PHP 5.5+) :

if (!empty($r->getError()))

Di mana getError()sederhananya:

public function getError()
{
    return $this->error;
}

Namun saya berakhir dengan kesalahan ini:

tidak dapat menggunakan nilai metode pengembalian dalam konteks tulis

Apa artinya ini? Bukankah ini hanya bacaan?

Extrakun
sumber
2
Mungkin dalam PHP 5.5 Anda akan diizinkan untuk memberikan ekspresi ke empty: wiki.php.net/rfc/empty_isset_exprs
Carlos Campderrós
Ok saya menemukan Jawaban porneL benar juga ini kode saya if ( !$e->find('div') ) yang memeriksa apakah elemen HTML DOM saat ini kosong atau tidak. Saya menggunakannya di dalam loop untuk mencetak hanya satu Div tanpa Div bagian dalamnya.
Salem

Jawaban:

769

empty() perlu mengakses nilai dengan referensi (untuk memeriksa apakah referensi itu menunjuk ke sesuatu yang ada), dan PHP sebelum 5.5 tidak mendukung referensi ke nilai sementara yang dikembalikan dari fungsi.

Namun, masalah sebenarnya yang Anda miliki adalah yang Anda gunakan empty()sama sekali, secara keliru percaya bahwa nilai "kosong" berbeda dari "salah".

Kosong hanyalah alias untuk !isset($thing) || !$thing. Ketika hal yang Anda periksa selalu ada (dalam hasil panggilan fungsi PHP selalu ada), empty()fungsi tidak lain adalah operator negasi .

PHP tidak memiliki konsep kekosongan . Nilai yang mengevaluasi ke false adalah kosong, nilai-nilai yang mengevaluasi ke benar adalah tidak kosong. Itu adalah hal yang sama. Kode ini:

$x = something();
if (empty($x)) 

dan ini:

$x = something();
if (!$x) 

selalu memiliki hasil yang sama, dalam semua kasus, untuk semua tipe data (karena $xdidefinisikan empty()adalah redundan).

Nilai kembali dari metode selalu ada (bahkan jika Anda tidak memiliki returnpernyataan, nilai balik ada dan berisi null). Karena itu:

if (!empty($r->getError()))

secara logis setara dengan:

if ($r->getError())
Kornel
sumber
29
Ini adalah jawaban yang jauh lebih baik daripada jawaban yang saat ini dipilih.
SystemParadox
20
@ gcb: tidak, manual PHP secara eksplisit mengatakan itu identik: "kosong () adalah kebalikan dari (boolean) var, kecuali bahwa tidak ada peringatan yang dihasilkan ketika variabel tidak disetel."
Kornel
16
Bagian yang tidak menghasilkan peringatan cukup penting ... kosong ($ var) akan mengembalikan true jika 0, '', array (), NULL, atau bahkan tidak didefinisikan. Ini praktik yang baik, terutama sehingga Anda dapat mencatat peringatan Anda yang sebenarnya tanpa mengisi file
landons
3
Ok, jawaban yang bagus, tapi apa cara yang benar untuk menghindari ini, adakah yang tahu?
Jelaskan
3
@EugenMihailescu secara umum itu ok, tapi itu tidak sepenuhnya setara dengan mengosongkan (), karena "", 0, dll "kosong", tapi tidak nol.
Kornel
330

Catatan: Ini adalah jawaban yang sangat tinggi dengan visibilitas tinggi, tetapi harap perhatikan bahwa ini mempromosikan praktik pengkodean yang buruk dan tidak perlu! Lihat jawaban @ Kornel untuk cara yang benar.

Catatan # 2: Saya mendukung saran untuk menggunakan jawaban @ Kornel . Ketika saya menulis jawaban ini tiga tahun yang lalu, saya hanya bermaksud menjelaskan sifat kesalahan, tidak harus mendukung alternatifnya. Cuplikan kode di bawah ini tidak disarankan.


Ini adalah batasan kosong () dalam versi PHP di bawah 5.5.

Catatan: kosong () hanya memeriksa variabel karena hal lain akan menghasilkan kesalahan parse. Dengan kata lain, yang berikut ini tidak akan berfungsi: kosong (trim ($ name)).

Anda harus mengubah ini

// Not recommended, just illustrates the issue
$err = $r->getError();
if (!empty($err))
Peter Bailey
sumber
156
Ini sangat kontraproduktif.
David Murdoch
47
Catatan: Hal yang sama berlaku dengan isset(). yaitu: isset($this->foo->getBar())akan menghasilkan masalah yang sama.
catchdave
7
jawaban porneL menjelaskan hal ini lebih terinci, dengan solusi yang lebih baik
SystemParadox
5
@ SystemParadox - Tergantung pada apa yang Anda maksud dengan "lebih baik". jawaban porneL bisa dibilang lebih menyeluruh dengan solusi "bersih", tetapi juga tidak benar-benar menjelaskan asal mula kesalahan.
Peter Bailey
4
Karena itu tidak salah, @menerima. Itu bukan jawaban terbaik, Anda tidak akan mendapatkan argumen dari saya di sana. Saya bahkan memilih porneL sendiri. Ini jawaban yang sangat lama tetapi tidak salah . Mengenai suara tinggi: ingat, porneL tiba hampir 17 bulan penuh setelah ini.
Peter Bailey
37

Menurut dokumen PHP :

kosong () hanya memeriksa variabel karena hal lain akan menghasilkan kesalahan parse

Anda tidak dapat menggunakan empty()secara langsung pada nilai pengembalian fungsi. Alih-alih, atur pengembalian dari getError()ke variabel dan jalankan empty()di variabel.

George Claghorn
sumber
19

Saya biasanya membuat fungsi global yang disebut is_empty () hanya untuk mengatasi masalah ini

function is_empty($var)
{ 
 return empty($var);
}

Maka di mana saja saya biasanya menggunakan kosong () Saya hanya menggunakan is_empty ()

Luke PM
sumber
2
Lebih baik untuk tidak melakukan ini dan tetap berpegang pada standar (mungkin menjengkelkan).
tonyhb
1
@dinamisme, bisakah Anda menjelaskan mengapa tidak?
Janis Veinbergs
1
Karena fungsi kenyamanan bisa jadi menyusahkan untuk membaca kode orang lain. Plus, dalam arsitektur MVC / HMVC dapat mengacaukan struktur Anda. Pada akhirnya, pembuat kode PHP harus mengetahui keterbatasannya dan dapat memahami solusi kecil tanpa fungsi kenyamanan.
tonyhb
14
Wow, Anda baru saja menemukan fungsi negasi . Anda tahu PHP punya !operator untuk ini? :)
Kornel
4

Seperti yang ditunjukkan oleh orang lain, itu adalah batasan (aneh) dari empty ().

Untuk sebagian besar tujuan, melakukan ini sama dengan memanggil kosong, tetapi ini berfungsi:

if ($r->getError() != '')
Jani Hartikainen
sumber
5
Ini tidak benar - empty()mencakup lebih banyak kemungkinan daripada hanya string kosong
Robbie Averill
3
Itu sebabnya ia mengatakan "untuk sebagian besar tujuan ", tidak semua
Jani Hartikainen
2

Masalahnya adalah ini, Anda ingin tahu apakah kesalahannya tidak kosong.

public function getError() {
    return $this->error;
}

Menambahkan metode isErrorSet () akan menyelesaikan masalah.

public function isErrorSet() {
    if (isset($this->error) && !empty($this->error)) {
        return true;
    } else {
        return false;
    }
}

Sekarang ini akan berfungsi dengan baik dengan kode ini tanpa pemberitahuan.

if (!($x->isErrorSet())) {
    echo $x->getError();
}
Jean Carlo Bambalan
sumber
-3

Cara alternatif untuk memeriksa apakah array kosong adalah:

count($array)>0

Ini bekerja untuk saya tanpa kesalahan itu

quardas
sumber