PHP и JSON Query для извлечения данных из Freebase - PullRequest
2 голосов
/ 24 декабря 2011

Мне нужно получить информацию о продакшн-компании и дистрибуционной компании для любого фильма, и я использую для этого Freebase. Бывает, я никогда не использовал JSON и не знаю, как интегрировать запрос с моим PHP-файлом.

Учебники, которые я читал, не совсем ясны по этому вопросу, поэтому я всегда прихожу сюда, чтобы получить помощь, которую всегда получаю! :)

Итак ... Информация, которую мне нужно извлечь, это Freebase Query Editor

И PHP, который у меня есть, таков (закомментированные строки - это строки, которые, я уверен, являются неправильными, и / или строки из учебника, за которыми я следовал без успеха здесь :

$moviename = "The Matrix";

// [{ "name": "The Matrix", "type": "/film/film", "production_companies": [{ "name": null }], "distributors": [{ "distributor": [{ "name": null }] }] }]
$simplequery = array('name'=>$moviename, 'type'=>"/film/film", 'production_companies'=>array('name'=>null));

//{"id":"/topic/en/philip_k_dick", "/film/writer/film":[]}
//$simplequery = array('id'=>$_POST["freebasewriter"], 'name'=>null, '/film/writer/film'=>array(array('name'=>null, 'id'=>null)));

$queryarray = array('q1'=>array('query'=>$simplequery));
$jsonquerystr = json_encode($queryarray);

#run the query
$apiendpoint = "http://sandbox.freebase.com/api/service/mqlread?queries";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$apiendpoint=$jsonquerystr");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$jsonresultstr = curl_exec($ch);
curl_close($ch); 

$jsonquerystr = urlencode(json_encode($queryarray) );

//print_r($resultarray);
//$produtoraarray = $resultarray["q1"]["result"]["production_companies"];
//print_r($produtoraarray);
//$produtorarray = $resultarray["q1"]["result"][];
//$freebaseserver = "http://sandbox.freebase.com";

Может ли кто-нибудь помочь мне здесь? Заранее спасибо!

Кстати, высоко ценю это и счастливого Рождества :)

EDIT @ Янир Шахак, ответ помог, и теперь я получаю это:

Array ( [code] => /api/status/ok [q1] => Array ( [code] => /api/status/error [messages] => Array ( [0] => Array ( [code] => /api/status/error/mql/result [info] => Array ( [count] => 3 [result] => Array ( [0] => Array ( [name] => Warner Bros. Entertainment ) [1] => Array ( [name] => Village Roadshow Pictures ) [2] => Array ( [name] => Silver Pictures ) ) ) [message] => Unique query may have at most one result. Got 3 [path] => production_companies [query] => Array ( [name] => The Matrix [production_companies] => Array ( [error_inside] => . [name] => ) [type] => /film/film ) ) ) ) [status] => 200 OK [transaction_id] => cache;cache02.sandbox.sjc1:8101;2011-12-24T02:01:34Z;0004 ) 

Теперь ... Как я могу извлечь данные из этого массива, который я могу использовать?

Этот код не работает, так как я получаю неопределенные индексы

//print_r($resultarray);
//$produtoraarray = $resultarray["q1"]["result"]["production_companies"];
//print_r($produtoraarray);
//$produtorarray = $resultarray["q1"]["result"][];
//$freebaseserver = "http://sandbox.freebase.com";

Ответы [ 2 ]

5 голосов
/ 26 декабря 2011

Ваш запрос возвращает ошибку, потому что в нем отсутствуют некоторые важные детали. Вы написали:

$simplequery = array('name'=>$moviename, 
                     'type'=>"/film/film", 
                     'production_companies'=>array('name'=>null));

, что соответствует следующему MQL-запросу:

{
  "name": "The Matrix", 
  "type": "/film/film", 
  "production_companies": {
    "name": null
  }
}

Это терпит неудачу, потому что часто существует более одного фильма с заданным названием, и может быть задействовано более одной продюсерской компании. Чтобы правильно обрабатывать эти случаи в MQL, вам нужно обернуть свойство production_companies, а также полный запрос в массивы, чтобы указать, что вы ожидаете нескольких результатов для этих частей запроса. В MQL это выглядит так:

[{
  "name": "The Matrix", 
  "type": "/film/film", 
  "production_companies": [{
    "name": null
  }]
}]

и в вашем коде это будет выглядеть примерно так:

$notsosimplequery = array(array('name'=>$moviename, 
                                'type'=>"/film/film",
                                'production_companies'=>array(array('name'=>null))));

Вам также следует рассмотреть возможность использования новой службы чтения MQL , которая работает быстрее и имеет более высокие ограничения на количество запросов, которые вы можете делать в день.

2 голосов
/ 24 декабря 2011

Все, что вам нужно сделать, это заменить:

$jsonquerystr = json_encode( $queryarray );

на:

$jsonquerystr = urlencode( json_encode( $queryarray ) );

Очевидно, вам необходимо закодировать специальные символы в строке json перед отправкой их в APIсервер, использующий cURL в качестве cURL, не сделает это за вас ...

Когда вы вернете свой результат, он будет в форме JSON (JavaScript Object Notation), который является другим способом представления данных (атрибуты и значения) так же, как XML.Вам нужно будет декодировать JSON (обратите внимание, что при отправке запроса вы кодировали JSON) и использовать результат в качестве объекта, например так:

$data = json_decode( $jsonresultstr );
foreach ( $data->q1->messages[ 0 ]->info->result as $company )
{
    echo( $company->name . "<br/>" );
}
...