New in API, request success in website but request fail using php (SSL certificate problem: self signed certificate in certificate chain)

Hi, I’m new in this API. Currently I want to use the API to show the bus schedule around my area. When I request through the API Explorer (using API Key), I receive the result with HTTP code 200 OK. However when I generate the php code through API Explorer, I got this error “SSL certificate problem: self signed certificate in certificate chain” Anyone has this problem as well? Anyone know the problem with the code?

Here is the php code generated by API Explorer

<?php $ch = curl_init(); $url = 'https://api.transport.nsw.gov.au/v1/gtfs/realtime/nswtrains'; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_HEADER, FALSE); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: apikey l7xxa515552811d24cc5a61e66c69dfcc4cf')); $response = curl_exec($ch); if ($response === FALSE) { die(curl_error($ch)); } curl_close($ch); var_dump($response); echo $response; ?>

Thank You

Seems like the PHP cURL extension might not have root SSL certificate installed. You’ll need to trust one of the certificates in the chain

Or, the simpler option would be to add a flag to ignore SSL verification:

<?php
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
?>

Great. Thank I received the response after I set the curl option. Is there any consequent for ignoring the SSL verification ? or is there any option to auto trust the SSL?

Also after I got the response, I expect the result will be in json format, but the response is like symbol, How am I suppose to decode it?

one more thing when I try to decode it using this
var_dump(json_decode($response));

I just received NULL

Here is part of the result using var_dump($response);
" 1.0����� 1� 167.1479888900 *4T.C.1675"247021��"24806��"248021��"24802e���������"248047F"24804ah�"24792�"24791e ����������"24811 ���������<"24821���������)"24832e���������"248330 ���������"24831e���������"248323e���������"248351���������"24841���������"24871���������"24861���������"24851� 2� 551.1479889200 *4T.C.551�"279018e���������M"279539Mp"27992���������("27912���������"27922���������8"27971a��"27931e����������"27941 ��"27942 �"28101� 3� 565.1479892860 *4T.C.565"279018e���������"2845146I"279084e���������a"279513e���������"279512e���������"279536ea���������"279537e���������u"279539 ��"27992 ���������"27982���������"28005���������"28002� 4� 589.1479870900 *4T.C.589�"28302��"28211��"28231��"28261��"28251��"28312a��"28353��"28351 ���������"28361 Y

Thank You

Ignoring the verification would mean that the connection is susceptible to a Man in the Middle Attack (MITM). In layman terms, someone with access to the network between you and TfNSW could potentially intercept the request. You cannot verify that the data you recieve is from TfNSW.

But since you aren’t exchanging any private or confidential information, it’s not really a concern.

Unfortunately, the real time feed is not serialised in a JSON format. The realtime feed is encoded in Google’s protocol buffer format with the GTFS-R specification.

Fortunately, there are PHP libraries to help you read this data: GitHub - drslump/Protobuf-PHP: PHP implementation of Google's Protocol Buffers with a protoc plugin compiler

You’ll need to compile your own PHP class using the GTFS-R proto file provided by TfNSW: https://opendata.transport.nsw.gov.au/sites/default/files/tfnsw-gtfs-realtime.proto_.txt

Hmm. After I read the site from the link you gave, I’m not quite sure how to do it. In protobuf, there are few codec such as binary, json, phparray, xml, etc. Which one I should use for decoding?

And I’m don’t really understand what you mean by “You’ll need to compile your own PHP class using the GTFS-R proto”

Is there any guide for it? or any sample project?

Thank You

I’ll see if I can help make it clearer :slight_smile:

The response data is encoded in a protocol buffer format, which is a binary encoding. Therefore, you’re decoding the data as a protocol buffer.

Protocol buffers are a way of encoding data, much like JSON or XML – however, there is no native PHP function to decode the protobuf data.

The advantage of protobuf over XML or JSON is that the data structure is pre-defined and not transmitted as part of the response, thus saving bandwidth.

Instead, the data structure is defined in a .proto file, like the one provided by TfNSW. The .proto provided by TfNSW is based on the GTFS-R specification, but varies slightly for backwards compatibility.


The particular implementation of protobuf for PHP I linked to requires you to “compile” a PHP class based on the vendor’s .proto file using the protoc plugin. GitHub - drslump/Protobuf-PHP: PHP implementation of Google's Protocol Buffers with a protoc plugin compiler

(Note that compile in this context simply means to generate a PHP class programatically using the protoc plugin and not “compiling” to machine code.)

Something like:

protoc-gen-php -o ./build tfnsw-gtfs-realtime.proto

Once you’ve compiled the PHP class, you can use the library:

<?php
require_once 'DrSlump/Protobuf.php';
\DrSlump\Protobuf::autoload();

// using cURL to fetch the data here
$response = curl_exec($ch);

$feed = new FeedMessage();
$feed->parse($response);
?>

As a sidenote, having gone through this myself, I highly recommend not using PHP to decode the data :wink:

Hmm. I see. It’s quite complicated to decode it. And I’m still quite confuse. So which language that you recommend for server side, so I can use it as my API end point of my app ? Thank You

From personal experience, the libraries for both Python and Node.js are quite accessible. This library for node has some good examples on how to get started

2 Likes

great. Thank You :smiley:

I use a python script that outputs the json formatted version of the file so you can use Jquery or import the data in a mysql DB. If you PM me I can provide you with the file.