PHP从远程URL读取JSON文件

I've got this issue, PHP and Laravel. I'm trying to read a JSON file from remote ULR:

https://services.realestate.com.au/services/listings/search?query={"channel":"buy","filters":{"propertyType":["house"],"surroundingSuburbs":"False","excludeTier2":"true","geoPrecision":"address","localities":[{"searchLocation":"Blacktown, NSW 2148"}]},"pageSize":"100"}

I used the code:

$re_url = 'https://services.realestate.com.au/services/listings/search?query={"channel":"buy","filters":{"propertyType":["house"],"surroundingSuburbs":"False","excludeTier2":"true","geoPrecision":"address","localities":[{"searchLocation":"Blacktown, NSW 2148"}]},"pageSize":"100"}';

$ch = curl_init($re_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$re_str = curl_exec($ch);
curl_close($ch);
$re_list = json_decode($re_str);

It kept receiving Error "An error occurred while processing your request. Reference #30.96464868.1492255689.1829cf2"

I tried url with "https://google.com.au", which worked ok, so it looks like the URL encode issue. But I'm not sure.

Can anyone help, or had the same issues?

Thanks

I believe you have two issues and that my code below will solve them. My code also uses a few different methodologies to avoid manual assembly of JSON, URL query strings, etc. (see lines 3-41 of the provided code)

Issues

  1. You are not encoding the query parameter values - can be fixed with urlencode of the param values, but I prefer http_build_query for reasons noted in my introductory paragraph.
  2. You are not sending a User Agent (UA) header (The distant end seems to require a value in this header but doesn't care what it is. Having received a request with a UA I think it must whitelist the IP for a few moments as it doesn't seem to require it on every request. I would just send it for every request, though, as it doesn't hurt and you never know when your whitelist will timeout). See lines 50-53 for what I set in this script and some options you have

Replacement Code

With explanatory comments

<?php

/*
 * The data that will be serialized as JSON and used as the value of the
 * `query` parameter in your URL query string
 */
$search_query_data = [
    "channel" => "buy",
    "filters" => [
        "propertyType" => [
            "house",
        ],
        "surroundingSuburbs" => "False",
        "excludeTier2" => "true",
        "geoPrecision" => "address",
        "localities" => [
            [
                "searchLocation" => "Blacktown, NSW 2148",
            ],
        ],
    ],
    "pageSize" => "100",
];

/*
 * Serialize the data as JSON
 */
$search_query_json = json_encode($search_query_data);

/*
 * Make a URL query string with a param named `query` that will be set as the
 * JSON from above
 */
$url_query_string = http_build_query([
    'query' => $search_query_json,
]);

/*
 * Assemble the URL to which we'll make the request, and set it into CURL
 */
$request_url = 'https://services.realestate.com.au/services/listings/search?' . $url_query_string;

$ch = curl_init($request_url);

/*
 * Set some CURL options
 */
// Have `curl_exec()` return the transfer as a string instead of outputting
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Set a user agent header
curl_setopt($ch, CURLOPT_USERAGENT, 'H.H\'s PHP CURL script');
// If you want to spoof, say, Safari instead, remove the last line and uncomment the next:
//curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30');

/*
 * Get the response and close out the CURL handle
 */
$response_body = curl_exec($ch);
curl_close($ch);

/*
 * Unserialize the response body JSON
 */
$search_results = json_decode($response_body);

Finally, as an aside, I would recommend you stop using CURL directly and start using a library to abstract away some of the HTTP interactions and to make your requests/responses start to fit better with "standard" (PSR) interfaces. Since you're using Laravel, you're already in an ecosystem with Composer, so you could easily install something like Guzzle.

I GUESS there may be 2 issues here that you need to overcome

The first one is very simple , you DO need to urlencode() after the "search?" some special characters just can not direct pass to the URL

The second issue , after urlencode, if it still not working , is the way you are sending to the service ,I have done with some APIs when they try to sending Json, they generally put it in the body and "POST" them,May be you should not pass them in the url (from the begining), of course , you only need to consider this if it still not working.

Try chrome postman first , you will love it.

$_curl = curl_init();
curl_setopt($_curl, CURLOPT_SSL_VERIFYHOST, 2); // you missing this line
curl_setopt($_curl, CURLOPT_SSL_VERIFYPEER, false); // you missing this line
curl_setopt($_curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($_curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($_curl, CURLOPT_URL, $re_url);
$rtn = curl_exec( $_curl );