Làm cách nào để file_get_contents () hoạt động với HTTPS?


106

Tôi đang tiến hành thiết lập xử lý thẻ tín dụng và cần sử dụng giải pháp thay thế cho CURL. Mã sau hoạt động tốt khi tôi đang sử dụng máy chủ thử nghiệm (không gọi URL SSL), nhưng bây giờ khi tôi kiểm tra nó trên máy chủ đang hoạt động với HTTPS, nó không thành công với thông báo lỗi "không mở được luồng".

function send($packet, $url) {
  $ctx = stream_context_create(
    array(
      'http'=>array(
        'header'=>"Content-type: application/x-www-form-urlencoded",
        'method'=>'POST',
        'content'=>$packet
      )
    )
  );
  return file_get_contents($url, 0, $ctx);
}

Câu trả lời:


89

Hãy thử tập lệnh sau để xem liệu có sẵn trình bao bọc https cho các tập lệnh php của bạn hay không.

$w = stream_get_wrappers();
echo 'openssl: ',  extension_loaded  ('openssl') ? 'yes':'no', "\n";
echo 'http wrapper: ', in_array('http', $w) ? 'yes':'no', "\n";
echo 'https wrapper: ', in_array('https', $w) ? 'yes':'no', "\n";
echo 'wrappers: ', var_export($w);

đầu ra phải giống như

openssl: yes
http wrapper: yes
https wrapper: yes
wrappers: array(11) {
  [...]
}

@volker Đó lý do tại sao tôi yêu cầu allow_url_fopen
Gordon

Chà, điều kỳ lạ là nó nói openssl đang tắt, nhưng theo phpinfo () thì nó được biên dịch với nó, trừ khi tôi thấy nó sai.
James Simpson

phpinfo () cho bạn biết như vậy trong dòng config hay toàn bộ phần được gọi là "OpenSSL"?
VolkerK

Được rồi, nó chỉ nằm trong dòng config, không phải một phần dành cho nó. Tôi đoán đó là vấn đề?
James Simpson

Tôi có tất cả những thứ đó và nó vẫn không hoạt động. Và allow_url_fopen. Chỉ các url không phải https mới hoạt động từ localhost.
Curtis

116

Để cho phép trình bao bọc https:

  • các php_opensslphần mở rộng phải tồn tại và được kích hoạt
  • allow_url_fopen phải được đặt thành on

Trong tệp php.ini, bạn nên thêm các dòng này nếu không tồn tại:

extension=php_openssl.dll

allow_url_fopen = On

Cả hai đều được cài là Bật trong cài đặt của tôi nhưng tôi vẫn nhận được lỗi SSL "Cảnh báo: file_get_contents (): SSL: Handshake timed out trong"
Adamantus

53

Hãy thử những điều sau đây.

function getSslPage($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

Lưu ý: Điều này vô hiệu hóa xác minh SSL, có nghĩa là bảo mật do HTTPS cung cấp sẽ bị mất . Chỉ sử dụng mã này để thử nghiệm / phát triển cục bộ, không bao giờ sử dụng trên internet hoặc các mạng công khai khác. Nếu mã này hoạt động, điều đó có nghĩa là chứng chỉ SSL không đáng tin cậy hoặc không thể được xác minh, bạn nên xem xét việc khắc phục như một vấn đề riêng biệt.


29
Tại sao bạn lại tắt xác minh ssl khi xử lý thẻ tín dụng?
Peter

Cảm ơn bạn, thủ thuật có ở đây: curl_setopt ($ ch, CURLOPT_SSL_VERIFYPEER, FALSE);
Dylan B

46
$url= 'https://example.com';

$arrContextOptions=array(
      "ssl"=>array(
            "verify_peer"=>false,
            "verify_peer_name"=>false,
        ),
    );  

$response = file_get_contents($url, false, stream_context_create($arrContextOptions));

Điều này sẽ cho phép bạn lấy nội dung từ url cho dù đó là HTTPS


Cảm ơn! Điều này đã làm việc cuối cùng của tôi. Đã cố gắng gọi FB Graph API mở :)
decodingpanda

Tôi đang cố gắng truy cập một miền của mình với chứng chỉ không hợp lệ chỉ cho mục đích thử nghiệm và mặc dù điều này vô hiệu hóa xác thực SSL, nhưng đó là những gì tôi cần.
carla

Tuyệt quá! Tôi đã cố gắng tải xuống lịch airbnb trong 5 ngày trên trang web thử nghiệm XAMPP của mình bằng cách sử dụng file_get_contents, điều này đã giải quyết được vấn đề, cảm ơn.
JohnnyBeGood

Đã làm việc cho tôi khi cố gắng kết nối với hộp kiểm tra Vagrant mà không có chứng chỉ HTTP hợp lệ qua https. Liên kết đến các tùy chọn ngữ cảnh SSL PHP đang được đặt tại đây: php.net/manual/en/context.ssl.php ; verify peer = Yêu cầu xác minh chứng chỉ SSL được sử dụng; verify_peer_name = Yêu cầu xác minh tên đồng đẳng.
Anthony

Đây không phải là vi phạm chứng nhận SSL và là một lỗ hổng bảo mật?
webchun

10

Điều này có thể là do máy chủ mục tiêu của bạn không có chứng chỉ SSL hợp lệ.


Máy chủ yêu cầu không cần có chứng chỉ SSL.
ceejayoz 29/12/09

15
Tôi không nói máy chủ yêu cầu, tôi nói máy chủ mục tiêu.
Emil Vikström

2
Điều đó sẽ dạy tôi đọc lướt. Hì hì! Xin vui lòng chấp nhận lời xin lỗi của tôi và ủng hộ.
ceejayoz 29/12/09

Máy chủ đích không có chứng chỉ SSL hợp lệ.
James Simpson

@James, bạn có gặp lỗi nếu thử kết nối bằng cURL không? Hay là hoàn toàn không thể thử?
Emil Vikström

6

Chỉ cần thêm hai dòng trong tệp php.ini của bạn.

extension=php_openssl.dll

allow_url_include = On

nó làm việc cho tôi.


1
Có thể ý bạn là allow_url_fopenvì câu hỏi liên quan đến việc mở url, không bao gồm.
shukshin.ivan

5

Tôi đã có những lỗi giống nhau. Thiết allow_url_include = Onphp.inicố định nó cho tôi.


5

HTTPS được hỗ trợ bắt đầu từ PHP 4.3.0, nếu bạn đã biên dịch để hỗ trợ OpenSSL. Ngoài ra, hãy đảm bảo máy chủ đích có chứng chỉ hợp lệ, tường lửa cho phép các kết nối gửi đi và allow_url_fopentrong php.ini được đặt thành true.


Tôi có PHP 5.2.8 với hỗ trợ OpenSSL. Tôi gặp lỗi tương tự với lỗi này và máy chủ đích có chứng chỉ hợp lệ.
James Simpson

2
tường lửa có được định cấu hình để cho phép các kết nối https đi không? Thông thường, máy chủ web chạy https không chạy trên cổng 80. Có lỗi gì khác ngoài lỗi 'không mở được luồng' không?
Gordon

1
Theo như tôi biết, đây là toàn bộ lỗi: Cảnh báo: fopen (https: // ...) [function.fopen]: không mở được luồng: Không có tệp hoặc thư mục như vậy trong / home / user / public_html / test.php trên dòng 993
James Simpson

và allow_url_fopen trong php.ini được đặt thành gì?
Gordon

Thật ki quặc. Bạn có thể thực hiện GET trên HTTP và url HTTPS để xem nó có hoạt động không? không có ngữ cảnh luồng?
Gordon

3

Trong trường hợp của tôi, sự cố là do WAMP sử dụng php.ini cho CLI khác với Apache, vì vậy cài đặt của bạn được thực hiện thông qua menu WAMP không áp dụng cho CLI. Chỉ cần sửa đổi CLI php.ini và nó hoạt động.


1

Đôi khi máy chủ sẽ chọn không phản hồi dựa trên những gì nó thấy hoặc không thấy trong tiêu đề yêu cầu http (chẳng hạn như tác nhân người dùng thích hợp). Nếu bạn có thể kết nối với một trình duyệt, hãy lấy các tiêu đề mà trình duyệt gửi và bắt chước chúng trong ngữ cảnh luồng của bạn.


0

Tôi đã gặp sự cố với https không hoạt động trên IIS. Đã giải quyết bằng:

file_get_contents ('https ..) sẽ không tải.

  • tải xuống https://curl.haxx.se/docs/caextract.html
  • cài đặt theo ..phpN.N / extras / ssl
  • chỉnh sửa php.ini bằng:

    curl.cainfo = "C: \ Program Files \ PHP \ v7.3 \ extras \ ssl \ cacert.pem" openssl.cafile = "C: \ Program Files \ PHP \ v7.3 \ extras \ ssl \ cacert.pem"

cuối cùng!


-1

ĐỂ KIỂM TRA NẾU CÓ URL LÊN HAY KHÔNG

Mã trong câu hỏi của bạn có thể được viết lại thành một phiên bản hoạt động:

function send($packet=NULL, $url) {
// Do whatever you wanted to do with $packet
// The below two lines of code will let you know if https url is up or not
$command = 'curl -k '.$url;
return exec($command, $output, $retValue);
}
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.