Bagaimana saya bisa menangani peringatan fungsi file_get_contents () di PHP?

312

Saya menulis kode PHP seperti ini

$site="http://www.google.com";
$content = file_get_content($site);
echo $content;

Tetapi ketika saya menghapus "http: //" dari $sitesaya mendapatkan peringatan berikut:

Peringatan: file_get_contents (www.google.com) [function.file-get-content]: gagal membuka streaming:

Saya mencoba trydan catchtetapi tidak berhasil.

Waseem
sumber
2
Juga pendekatan yang menarik: stackoverflow.com/questions/6718598/…
Hugo Stieglitz
Terkait: stackoverflow.com/q/2002610
Fr0zenFyr
Gunakan try-catch dengan set_error_handler-function seperti yang dikatakan di sini stackoverflow.com/a/3406181/1046909
MingalevME
2
Jika Anda menghapus http: // dari url, maka Anda mencari file "www.google.com" di disk lokal Anda.
Rauli Rajande
Bagaimana ini bisa mendapatkan begitu banyak perhatian dan peningkatan. Mengapa Anda menghapus informasi protokol. Bahkan pada 2008, Anda memiliki FTP dan HTTPS.
Daniel W.

Jawaban:

507

Langkah 1: periksa kode pengembalian: if($content === FALSE) { // handle error here... }

Langkah 2: tekan peringatan dengan meletakkan operator kontrol kesalahan (mis. @) Di depan panggilan ke file_get_contents () : $content = @file_get_contents($site);

Roel
sumber
86
Ingatlah untuk menggunakan perbandingan ketat: if ($ content === FALSE). Jika file tersebut berisi "0", maka itu akan memicu false negative.
Aram Kocharyan
7
Hai, ini tidak berfungsi untuk saya, menambahkan @ masih menyebabkan E_WARNING ditangkap oleh beberapa penangan kesalahan global (bukan milik saya), dan skrip saya mati sebelum saya memiliki kesempatan untuk menangani nilai kembali. Ada ide? tnx.
Sagi Mann
1
Efek samping terdeteksi: jika file tidak ada, skrip berhenti di baris @file_get_contents.
Dax
Ini tidak bekerja untuk saya, bahkan jika ini akan menjadi solusi yang tepat. Saya memiliki peringatan batas waktu tanpa data yang diterima, tetapi $ content === FALSE tidak "dipicu" ($ situs dipanggil dari server localhost, perhatikan bahwa saya memiliki data dengan cepat jika saya menyisipkan sendiri url ke browser).
Oliver
4
Meskipun jawabannya sudah sangat lama, saya tetap menyarankan untuk menambahkan catatan pada jawaban Anda bahwa penggunaan @dapat berdampak negatif pada kinerja. Lihat jawaban ini pada posting terkait yang menjelaskan dengan cukup baik.
Fr0zenFyr
148

Anda juga dapat mengatur penangan kesalahan Anda sebagai fungsi anonim yang memanggil Pengecualian dan menggunakan coba / menangkap pengecualian itu.

set_error_handler(
    function ($severity, $message, $file, $line) {
        throw new ErrorException($message, $severity, $severity, $file, $line);
    }
);

try {
    file_get_contents('www.google.com');
}
catch (Exception $e) {
    echo $e->getMessage();
}

restore_error_handler();

Sepertinya banyak kode untuk menangkap satu kesalahan kecil, tetapi jika Anda menggunakan pengecualian di seluruh aplikasi Anda, Anda hanya perlu melakukan ini sekali, jauh di atas (dalam file konfigurasi yang disertakan, misalnya), dan itu akan ubah semua kesalahan Anda menjadi Pengecualian di seluruh.

enobrev
sumber
Ini adalah salah satu peningkatan PHP terhebat yang pernah saya lihat sejauh ini. Terima kasih enobrev
Tomasz Smykowski
@ enobrev, Mengapa Anda memberi nilai yang sama untuk nomor kesalahan dan tingkat keparahan?
Pacerier
Tidak ada alasan khusus selain cara menawarkan sesuatu yang berguna dalam $ exception-> getCode (), karena set_error_handler tidak menawarkan variabel nomor kesalahan (sayangnya).
enobrev
1
@ enobrev Jangan lupa untuk mengembalikan penangan kesalahan di dalam fungsi anonim sebelum melempar pengecualian. Pengecualian dapat ditangani dan dalam hal ini pawang masih diatur untuk melempar pengecualian khusus ini yang mungkin datang sebagai hal yang tidak terduga dan memperkenalkan perilaku aneh, sulit di-debug, ketika ada kesalahan lain dalam penanganan pengecualian.
Josef Sábl
1
Saya akan merekomendasikan untuk memasukkan restore_error_handler () panggilan akhirnya blok
peschanko
67

Cara favorit saya untuk melakukan ini cukup sederhana:

if (!$data = file_get_contents("http://www.google.com")) {
      $error = error_get_last();
      echo "HTTP request failed. Error was: " . $error['message'];
} else {
      echo "Everything went better than expected";
}

Saya menemukan ini setelah bereksperimen dengan try/catchdari @enobrev di atas, tetapi ini memungkinkan untuk kode yang kurang panjang (dan IMO, lebih mudah dibaca). Kami hanya menggunakan error_get_lastuntuk mendapatkan teks dari kesalahan terakhir, dan file_get_contentsmengembalikan false pada kegagalan, sehingga "jika" sederhana dapat menangkap itu.

Laurie
sumber
2
Ini adalah solusi termudah dan terbaik untuk masalah ini! Mungkin membuatnya @file_get_contentsuntuk menekan pelaporan kesalahan ke browser.
EDP
1
Saya akui bahwa di antara semua jawaban ini adalah satu-satunya jawaban yang masuk akal - jika kita ingin menambahkannya @file_get_contentsuntuk menekan peringatan dan menguji nilai hasil menggunakan === FALSE.
kostix
11
Ini akan memicu kesalahan untuk permintaan yang berhasil yang tidak mengembalikan badan, atau mengembalikan yang menilai salah. Seharusnyaif (false !== ($data = file_get_contents ()))
GordonM
Dokumentasi tidak memperjelasnya, tetapi menggunakan @ dapat menyebabkan error_get_lasttidak ada hasil dalam pengalaman saya
Glenn Schmidt
33

Anda dapat menambahkan sebuah @: $content = @file_get_contents($site);

Ini akan menekan peringatan apa pun - gunakan dengan hemat! . Lihat Operator Kontrol Kesalahan

Sunting: Ketika Anda menghapus 'http: //' Anda tidak lagi mencari halaman web, tetapi file di disk Anda disebut "www.google ....."

Greg
sumber
Itulah satu-satunya hal yang benar-benar berfungsi - saya tidak bisa menekan pesan "gagal membuka aliran" dengan cara lain.
Olaf
21

Salah satu alternatif adalah untuk menekan kesalahan dan juga melemparkan pengecualian yang bisa Anda tangkap nanti. Ini sangat berguna jika ada beberapa panggilan ke file_get_contents () dalam kode Anda, karena Anda tidak perlu menekan dan menangani semuanya secara manual. Sebagai gantinya, beberapa panggilan dapat dilakukan untuk fungsi ini dalam satu blok coba / tangkap.

// Returns the contents of a file
function file_contents($path) {
    $str = @file_get_contents($path);
    if ($str === FALSE) {
        throw new Exception("Cannot access '$path' to read contents.");
    } else {
        return $str;
    }
}

// Example
try {
    file_contents("a");
    file_contents("b");
    file_contents("c");
} catch (Exception $e) {
    // Deal with it.
    echo "Error: " , $e->getMessage();
}
Aram Kocharyan
sumber
15

Begini cara saya melakukannya ... Tidak perlu blok coba-tangkap ... Solusi terbaik selalu yang paling sederhana ... Selamat menikmati!

$content = @file_get_contents("http://www.google.com");
if (strpos($http_response_header[0], "200")) { 
   echo "SUCCESS";
} else { 
   echo "FAILED";
} 

sumber
4
-1: ini berfungsi jika Anda mendapatkan kesalahan 404 atau sesuatu, tetapi tidak jika Anda gagal terhubung ke server sama sekali (mis. Nama domain yang salah). Saya pikir $http_response_headertidak diperbarui dalam kasus itu, karena tidak ada respons HTTP yang diterima.
Nathan Reed
1
Seperti yang dikatakan @NathanReed, Anda harus memeriksa $ content tidak salah (dengan ===) karena itulah yang akan dikembalikan jika permintaan gagal terhubung sama sekali
Seb
15
function custom_file_get_contents($url) {
    return file_get_contents(
        $url,
        false,
        stream_context_create(
            array(
                'http' => array(
                    'ignore_errors' => true
                )
            )
        )
    );
}

$content=FALSE;

if($content=custom_file_get_contents($url)) {
    //play with the result
} else {
    //handle the error
}
RafaSashi
sumber
Ini tidak berfungsi. Jika $url404 tidak ditemukan, peringatan akan tetap muncul.
Raptor
Right Raptor, saya telah meningkatkan jawabannya dengan stream_context_create (); Tidak ada yang lebih baik ... "@" tidak dianjurkan
RafaSashi
1
ignore_errorshanya menginstruksikan konteks HTTP untuk tidak menafsirkan kode status respons HTTP > = 400 sebagai kesalahan. Sementara sedikit terkait, itu tidak menjawab pertanyaan penanganan kesalahan PHP.
matahari
Terima kasih atas ignore_errorsopsi! Inilah yang saya butuhkan!
Modder
6

Inilah cara saya mengatasinya:

$this->response_body = @file_get_contents($this->url, false, $context);
if ($this->response_body === false) {
    $error = error_get_last();
    $error = explode(': ', $error['message']);
    $error = trim($error[2]) . PHP_EOL;
    fprintf(STDERR, 'Error: '. $error);
    die();
}
Jrm
sumber
4

Hal terbaik adalah mengatur kesalahan Anda sendiri dan penangan pengecualian yang akan melakukan sesuatu yang berguna seperti mencatatnya dalam file atau mengirim email yang kritis. http://www.php.net/set_error_handler


sumber
1

Anda dapat menggunakan skrip ini

$url = @file_get_contents("http://www.itreb.info");
if ($url) {
    // if url is true execute this 
    echo $url;
} else {
    // if not exceute this 
    echo "connection error";
}
ogie
sumber
Ini perlu perbandingan yang ketat: if ($url === true)...karena jika Anda mendapatkan sebagai respons 0atau kosong, itu menimbulkan kesalahan koneksi.
Daniel W.
1

Karena PHP 4 gunakan error_reporting () :

$site="http://www.google.com";
$old_error_reporting = error_reporting(E_ALL ^ E_WARNING);
$content = file_get_content($site);
error_reporting($old_error_reporting);
if ($content === FALSE) {
    echo "Error getting '$site'";
} else {
    echo $content;
}
Bob Stein
sumber
1

Cara termudah untuk melakukan ini adalah hanya menambahkan @ sebelum file_get_contents, i. e .:

$content = @file_get_contents($site); 
Muhammad Adeel Malik
sumber
1

sesuatu seperti ini:

public function get($curl,$options){
    $context = stream_context_create($options);
    $file = @file_get_contents($curl, false, $context);
    $str1=$str2=$status=null;
    sscanf($http_response_header[0] ,'%s %d %s', $str1,$status, $str2);
    if($status==200)
        return $file        
    else 
        throw new \Exception($http_response_header[0]);
}
Michael de Oz
sumber
1
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}
Frank Rich
sumber
-2

Anda harus menggunakan fungsi file_exists () sebelum menggunakan file_get_contents (). Dengan cara ini Anda akan menghindari peringatan php.

$file = "path/to/file";

if(file_exists($file)){
  $content = file_get_contents($file);
}
Jesús Díaz
sumber
Ini hanya akan berfungsi, jika Anda memanggil file lokal dan Anda memiliki izin yang tepat untuk memeriksa file lokal jika ada
rubo77
-3

Ubah file php.ini

allow_url_fopen = On

allow_url_include = On
Antério Vieira
sumber
Jangan lakukan ini. Terutama jangan izinkan url disertakan. Jangan, percayalah. Ini telah dinonaktifkan secara default karena alasan yang sangat bagus # c99.
Daniel W.
-3

Ini akan mencoba untuk mendapatkan data, jika tidak berhasil, itu akan menangkap kesalahan dan memungkinkan Anda untuk melakukan apa pun yang Anda butuhkan dalam tangkapan.

try {
    $content = file_get_contents($site);
} catch(\Exception $e) {
    return 'The file was not found';
}
Brad
sumber
-3
try {
   $site="http://www.google.com";
   $content = file_get_content($site);
   echo $content;
} catch (ErrorException $e) {
    // fix the url

}

set_error_handler(function ($errorNumber, $errorText, $errorFile,$errorLine ) 
{
    throw new ErrorException($errorText, 0, $errorNumber, $errorFile, $errorLine);
});
kta
sumber
file_get_content tidak selalu memberikan pengecualian
marlar
Apakah Anda ingin mengedit jawaban Anda dan memberi tahu kami bahwa pada waktu berapa file_get_content mengeluarkan pengecualian?
Ravinder Payal
1
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang mengapa dan / atau bagaimana kode ini menjawab pertanyaan meningkatkan nilai jangka panjangnya.
Jay Blanchard
-3

Anda juga harus mengatur

allow_url_use = On 

di Anda php.iniuntuk berhenti menerima peringatan.

GHAV
sumber