I wrote a small PHP application several months ago that uses the WordPress XMLRPC library to synchronize two separate WordPress blogs. I have a general "RPCRequest" function that packages the request, sends it, and returns the server response, and I have several more specific functions that customize the type of request that is sent.
In this particular case, I am calling "getPostIDs" to retrieve the number of posts on the remote server and their respective postids. Here is the code:
$rpc = new WordRPC('http://mywordpressurl.com/xmlrpc.php', 'username', 'password');
$rpc->getPostIDs();
I'm receiving the following error message:
expat reports error code 5
description: Invalid document end
line: 1
column: 1
byte index: 0
total bytes: 0
data beginning 0 before byte index:
Kind of a cliffhanger ending, which is also strange. But since the error message isn't formatted in XML, my intuition is that it's the local XMLRPC library that is generating the error, not the remote server.
Even stranger, if I change the "getPostIDs()" call to "getPostIDs(1)" or any other integer, it works just fine.
Here is the code for the WordRPC class:
public function __construct($url, $user, $pass) {
$this->url = $url;
$this->username = $user;
$this->password = $pass;
$id = $this->RPCRequest("blogger.getUserInfo",
array("null", $this->username, $this->password));
$this->blogID = $id['userid'];
}
public function RPCRequest($method, $params) {
$request = xmlrpc_encode_request($method, $params);
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: text/xml",
'content' => $request
)));
$file = file_get_contents($this->url, false, $context);
return xmlrpc_decode($file);
}
public function getPostIDs($num_posts = 0) {
return $this->RPCRequest("mt.getRecentPostTitles",
array($this->blogID, $this->username,
$this->password, $num_posts));
}
As I mentioned, it works fine if "getPostIDs" is given a positive integer argument. Furthermore, this used to work perfectly well as is; the default parameter of 0 simply indicates to the RPC server that it should retrieve all posts, not just the most recent $num_posts posts. Only recently has this error started showing up.
I've tried googling the error without much luck. My question, then, is what exactly does "expat reports error code 5" mean, and who is generating the error? Any details/suggestions/insights beyond that are welcome, too!
#Novak: Thanks for your suggestion. The problem turned out to be a memory issue; by retrieving all the posts from the remote location, the response exceeded the amount of memory PHP was allowed to utilize, hence the unclosed token error.
The problem with the cryptic and incomplete error message was due to an outdated version of the XML-RPC library being used. Once I'd upgraded the version of WordPress, it provided me with the complete error output, including the memory error.
i fixed this error installing php-xmlrpc module on apache
php-xmlrpc.x86_64 : A module for PHP applications which use the XML-RPC protocol
Expat is the XML parser in PHP. Error code 5 is one of many expat error constants, in this case: XML_ERROR_UNCLOSED_TOKEN. Sounds to me like there's an error in the result returned from the RPC call. You might want to do some error checking in RPCRequest after file_get_contents and before xmlrpc_decode.
Related
$FM_CONNECT = array(
'DB_FILE' => 'webaccess'
);
require_once "__app/dbConnect/FM.php";
require_once "__app/environmentSettings/environmentSettings.php";
$layout = 'webAccess';
$findCommand =& $fm->newFindCommand($layout);
$findCommand->addFindCriterion('AccountName', $_POST['username']);
$result = $findCommand->execute();
if(FileMaker::isError($result)){
FMExit(array(
'code' => 1,
'mes' => $result->getMessage()
));
}
$records = $result->getRecords();
When I try send some request to FileMaker server it return.
"XML error: Not well-formed (invalid token) at line 1"
I haven't change the code for a few weeks and I didn't see this error before.
Has anyone else experienced something like this?
This looks like FileMaker php api. If it is the case, you are missing the connection. If you just omitted the connection code from your code (since you get the error from the server), look at your request and check that XML is well formed. I can't check the request as you did not post it.
Make sure the web publishing engine is started and working. I faced this problem already and in my case the WPE was stopped suddenly. I started the WPE from the admin console and it was fine.
I am following the example at https://getstream.io/get_started/?language=php to understand how getstream io works. I ran into an error that got me confused.
require_once './vendor/autoload.php';
$client = new GetStream\Stream\Client('YOUR_API_KEY', 'API_KEY_SECRET');
$chris = $client->feed('user', 'chris');
// I replaced Your api key and api key secret with the one in my dashboard
// Add an activity; message is a custom field - tip: add unlimited custom fields!
$data = array(
"actor" => "chris",
"verb" => "add",
"object" => "picture:10",
"foreign_id" => "picture:10",
"message" => "Beautiful bird. Absolutely beautiful. Phenomenal bird."
);
$chris->addActivity($data);
// jack's 'timeline' feed follows chris' 'user' feed:
$jack = $client->feed('timeline', 'jack');
$jack->followFeed('user', 'chris');
// Read the 'timeline' feed for jack, chris' post will now show up:
$activities = $jack->getActivities(10);
var_dump($activities);
In my composer.json file I did this
"require": {
"get-stream/stream": "2.2.8"
}
I tried the above code on my localhost machine on windows but got this error
Fatal error: Uncaught exception 'GuzzleHttp\ExceptionConnectException' with message 'cURL error 28: Operation timed out after 0 milliseconds with 0 out of 0 bytes received (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)' in C:\xampp\htdocs\CorpersMate\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 186
GuzzleHttp\Exception\ConnectException: cURL error 28: Operation timed out after 0 milliseconds with 0 out of 0 bytes received (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in C:\xampp\htdocs\CorpersMate\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php on line 186
any ideas guys?
You should provide guide - we have to register first to get it, it can't happen.
Change second line to
$client = new GetStream\Stream\Client(KEY, SECRET);
I later found a tweak to the problem. The problem is with the guzzle library which is trying to verify my certificate. Because I needed a way to test it on local server before moving to production server, I had to modify the client constructor in the guzzle library and that solved the problem for me.
// file name is Client.php
public function __construct(array $config = ['verify' => false]) {
if (!isset($config['handler'])) {
$config['handler'] = HandlerStack::create();
}
// Convert the base_uri to a UriInterface
if (isset($config['base_uri'])) {
$config['base_uri'] = Psr7\uri_for($config['base_uri']);
}
$this->configureDefaults($config);
}
I'll dig into why this doesn't work on Xampp for you. Can you send us your cURL options, library version, etc.?
In the meantime, based on the workflow you've built:
build a feed for Chris
build an activity and put it on Chris' feed
build a feed for Jack
Jack follows Chris' feed
read Jack's feed and expect to see Chris' activity
... Jack will need to specify a number of activities to copy when following Chris' feed, otherwise Jack will only see updates from that point on; Jack will never see "picture:10" from Chris. There's a third optional parameter you can send through followFeed() that specifies how many items to copy to Jack's feed when you start following:
$jack->followFeed('user', 'chris', 100);
Or you can move step 4 between step 1 and 2. If Jack follows Chris before Chris adds a photo, it should show up on Jack's feed.
I'm working on trace logger of sorts that pushes log message requests onto a Queue on a Service Bus, to later be picked off by a worker role which would insert them into the table store. While running on my machine, this works just fine (since I'm the only one using it), but once I put it up on a server to test, it produced the following error:
HTTP_Request2_MessageException: Malformed response: in D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2\Adapter\Socket.php on line 1013
0 HTTP_Request2_Response->__construct('', true, Object(Net_URL2)) D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2\Adapter\Socket.php:1013
1 HTTP_Request2_Adapter_Socket->readResponse() D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2\Adapter\Socket.php:139
2 HTTP_Request2_Adapter_Socket->sendRequest(Object(HTTP_Request2)) D:\home\site\wwwroot\vendor\pear-pear.php.net\HTTP_Request2\HTTP\Request2.php:939
3 HTTP_Request2->send() D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\Common\Internal\Http\HttpClient.php:262
4 WindowsAzure\Common\Internal\Http\HttpClient->send(Array, Object(WindowsAzure\Common\Internal\Http\Url)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\Common\Internal\RestProxy.php:141
5 WindowsAzure\Common\Internal\RestProxy->sendContext(Object(WindowsAzure\Common\Internal\Http\HttpCallContext)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\Common\Internal\ServiceRestProxy.php:86
6 WindowsAzure\Common\Internal\ServiceRestProxy->sendContext(Object(WindowsAzure\Common\Internal\Http\HttpCallContext)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\ServiceBus\ServiceBusRestProxy.php:139
7 WindowsAzure\ServiceBus\ServiceBusRestProxy->sendMessage('<queuename>/mes…', Object(WindowsAzure\ServiceBus\Models\BrokeredMessage)) D:\home\site\wwwroot\vendor\microsoft\windowsazure\WindowsAzure\ServiceBus\ServiceBusRestProxy.php:155
⋮
I've seen previous posts that describe similar issues; Namely:
Windows Azure PHP Queue REST Proxy Limit (Stack Overflow)
Operations on HTTPS do not work correctly (GitHub)
That imply that this is a known issue regarding the PHP Azure Storage libraries, where there are a limited amount of HTTPS connections allowed. Before requirements were changed, I was accessing the table store directly, and ran into this same issue, and fixed it in the way the first link describes.
The problem is that the Service Bus endpoint in the connection string, unlike Table Store (etc.) connection string endpoints, MUST be 'HTTPS'. Trying to use it with 'HTTP' will return a 400 - Bad Request error.
I was wondering if anyone had any ideas on a potential workaround. Any advice would be greatly appreciated.
Thanks!
EDIT (After Gary Liu's Comment):
Here's the code I use to add items to the queue:
private function logToAzureSB($source, $msg, $severity, $machine)
{
// Gather all relevant information
$msgInfo = array(
"Severity" => $severity,
"Message" => $msg,
"Machine" => $machine,
"Source" => $source
);
// Encode it to a JSON string, and add it to a Brokered message.
$encoded = json_encode($msgInfo);
$message = new BrokeredMessage($encoded);
$message->setContentType("application/json");
// Attempt to push the message onto the Queue
try
{
$this->sbRestProxy->sendQueueMessage($this->azureQueueName, $message);
}
catch(ServiceException $e)
{
throw new \DatabaseException($e->getMessage, $e->getCode, $e->getPrevious);
}
}
Here, $this->sbRestProxy is a Service Bus REST Proxy, set up when the logging class initializes.
On the recieving end of things, here's the code on the Worker role side of this:
public override void Run()
{
// Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
Client.OnMessage((receivedMessage) =>
{
try
{
// Pull the Message from the recieved object.
Stream stream = receivedMessage.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string message = reader.ReadToEnd();
LoggingMessage mMsg = JsonConvert.DeserializeObject<LoggingMessage>(message);
// Create an entry with the information given.
LogEntry entry = new LogEntry(mMsg);
// Set the Logger to the appropriate table store, and insert the entry into the table.
Logger.InsertIntoLog(entry, mMsg.Service);
}
catch
{
// Handle any message processing specific exceptions here
}
});
CompletedEvent.WaitOne();
}
Where Logging Message is a simple object that basically contains the same fields as the Message Logged in PHP (Used for JSON Deserialization), LogEntry is a TableEntity which contains these fields as well, and Logger is an instance of a Table Store Logger, set up during the worker role's OnStart method.
This was a known issue with the Windows Azure PHP, which hasn't been looked at in a long time, nor has it been fixed. In the time between when I posted this and now, We ended up writing a separate API web service for logging, and had our PHP Code send JSON strings to it over cURL, which works well enough as a temporary work around. We're moving off of PHP now, so this wont be an issue for much longer anyways.
I am feebly trying to implement a stamps.com api interface into my platform. This is my first time using SOAP, I event had to recompile PHP to enable the libraries.
I'm moving along but now I'm having a problem. They support soap 1.1 and soap 1.2 requests, and when I run the following code:
$client = new SOAPClient(
'./SWSIM.wsdl',
array(
'trace' => 1
)
);
I get back a successful response from my request that comes after this.
However if I add the option to use soap 1.2 like this:
$client = new SOAPClient(
'./SWSIM.wsdl',
array(
'trace' => 1,
'soap_version' => SOAP_1_2
)
);
I get the following error:
There was an exception running the extensions specified in the config file. ---> Value cannot be null. Parameter name: input
This line is not actually throwing the exception. Its the following command that throws it, but removing the soap_version is what "fixes it". I would like to use soap 1.2 so naturally this is bugging me.
FTR The command I'm running is this:
$authData = array(
"Credentials" => array(
"IntegrationID" => "MYUID",
"Username" => "MYUSERNAME",
"Password" => "MYPASSWORD"
)
);
try {
$objectresult = $client->AuthenticateUser($authData);
} catch (Exception $e) {
echo "EXCEPTION: " . $e->getMessage();
print_r($e);
exit;
}
The WSDL file can be viewed here:
https://swsim.stamps.com/swsim/swsimv22.asmx?wsdl
I have also checked in with their developer support and they said:
"The message you are currently receiving is returned from whichever program you are designing your integration with. This has been commonly noted happening within Visual Basic where is creates a wrapper class that needs certain variables for the response. This could be similar to the behavior that you are experiencing. Please verify how your program language consumes a WSDL."
I also noticed that the __soapCall method excepts an "input headers" argument. I'm not entirely sure I should be / can even use that method in my code. I suppose I should just try and play with it.
Check your WSDL file. I was using the wrong one, and it appears you may be as well. Try this one: http://developer.stamps.com/developer/downloads/files/Stamps.com_SWSIM.wsdl
NOTE: The above is out of date. Contact stamps.com for the current wsdl!
I know this is an old thread, but here is an example class that should get anyone started with the stamps.com api in php https://github.com/aaronjsmith/stamps.com-php
The WSDL looks fine and it's the same input structure for both Soap versions. The problem is a bug somewhere at their end, you'll have to contact them to resolve.
I would also test it via a .NET app just to see if it behaves the same.
I am trying to use a function from SOAP, which will fetch details about a specific news item. The problem is that I don't get the expected results, just a a strange error. I am using the built-in SOAP client in PHP5.
My error is:
Fatal error: Uncaught SoapFault
exception: [Client] SOAP-ERROR:
Encoding: External reference
'https://newsclient.omxgroup.com/cdsPublic/viewDisclosure.action?disclosureId=379485&messageId=454590'
in
/home/********/public_html/********/updatenews3.php:15
My code is:
<?php
$login = '***';
$password = '***';
$client = new SoapClient(
'https://newsclient.omxgroup.com/wsdl/DisclosureNewsService.wsdl',
array(
'login' => $login,
'password' => $password
));
$param = array('lastPublicationId' => 361825);
$result = $client->fetchNews($param);
?>
The error is the same for all lastPublicationId, where a result is found. It seems as if PHP is trying to load a link, which is found somewhere in the XML-reply (the URL, which is in the error message), and can't access it. Even though I have googled this a lot, I can't find any solution. The only thing I can find is that this seems to have been reported as a bug in a previous version of PHP, but the error refers to PHP 5.2.2 Since I'm using PHP 5.2.9, I'm thinking it can't be that. I'm suspecting the &-character to be the cause of this error?
The WSDL-file can be found here: https://newsclient.omxgroup.com/wsdl/DisclosureNewsService.wsdl
Does somebody know this error, and know of any solution?
It's possible that the XML being returned by $client->fetchNews($param); isn't being escaped properly - there seems to be an unescaped & in the URL which is shown in the error message.
Best thing is probably to check exactly what XML is being returned, by turning on tracing and printing the last response:
$client = new SoapClient(
'https://newsclient.omxgroup.com/wsdl/DisclosureNewsService.wsdl',
array(
'login' => $login,
'password' => $password,
'trace' => 1
));
$param = array('lastPublicationId' => 361825);
try {
$result = $client->fetchNews($param);
}
catch (SoapFault $sf) {
print '<pre>';
// print the exception
print_r($sf);
// print the XML response
print $client->__getLastResponse();
}
A workaround (if the server is returning invalid XML) is to use code similar to the above to catch the exception. You can then manually get at the XML returned (using __getLastResponse()), and clean it up yourself (e.g. using htmlenties or a regexp), before returning it and using it in the rest of your application.