PHP Logophpxmlrpc/phpxmlrpc

phpxmlrpc is a robust and mature PHP library that provides comprehensive support for implementing both XML-RPC clients and servers. XML-RPC (XML Remote Procedure Call) is a simple, stateless, and lightweight remote procedure call protocol that uses XML to encode its calls and HTTP as a transport mechanism. It allows different systems, possibly running different operating systems and programming languages, to communicate and invoke procedures on each other over a network.\n\nKey Aspects of phpxmlrpc/phpxmlrpc:\n* Interoperability: Facilitates communication between PHP applications and systems developed in other languages (Java, Python, .NET, etc.) that also support XML-RPC.\n* Client Implementation: Provides classes and methods to easily construct XML-RPC requests, send them to a remote server, and parse the responses. It handles the serialization of PHP data types into XML-RPC compatible types and deserialization back into PHP.\n* Server Implementation: Offers tools to create XML-RPC servers in PHP. It can listen for incoming XML-RPC requests, dispatch them to appropriate PHP functions, and generate XML-RPC responses, including proper error handling.\n* Data Type Mapping: Manages the mapping between PHP data types (strings, integers, floats, booleans, arrays, structs) and XML-RPC data types, ensuring proper serialization and deserialization.\n* Error Handling: Supports standard XML-RPC error reporting, allowing servers to send detailed error messages and clients to gracefully handle received faults.\n* Transport Flexibility: While typically using HTTP POST, the library focuses on the XML-RPC payload, making it adaptable to various HTTP client implementations.\n\nWhen to Use phpxmlrpc:\nIt's particularly useful when integrating with older systems or services that predominantly use XML-RPC for their API. While newer protocols like REST and gRPC are more common for modern web services, XML-RPC remains a viable and simpler alternative for specific scenarios, especially where the payload is not overly complex and a lightweight RPC mechanism is preferred over more complex protocols like SOAP.\n\nInstallation:\nThe library is typically installed via Composer: `composer require phpxmlrpc/phpxmlrpc`.

Example Code

```php
<?php

require_once __DIR__ . '/vendor/autoload.php';

use PhpXmlRpc\Value;
use PhpXmlRpc\Request;
use PhpXmlRpc\Client;
use PhpXmlRpc\Server;

// --- XML-RPC Server Example ---
// Save this as 'server.php'

function addNumbers($methodName, $params)
{
    // $params is an array of PhpXmlRpc\Value objects
    if (count($params) !== 2) {
        return new PhpXmlRpc\Response(0, 1, 'Two numbers required.');
    }

    $num1 = $params[0]->scalarval();
    $num2 = $params[1]->scalarval();

    if (!is_numeric($num1) || !is_numeric($num2)) {
        return new PhpXmlRpc\Response(0, 2, 'Both parameters must be numbers.');
    }

    $result = $num1 + $num2;
    return new PhpXmlRpc\Response(new Value($result, Value::TYPE_INT));
}

// Define methods the server will expose
$my_methods = [
    'sample.add' => [
        'function' => 'addNumbers',
        'signature' => [['int', 'int', 'int']], // return_type, param1_type, param2_type
        'docstring' => 'Adds two integers together.'
    ],
    // You can add more methods here
    // 'sample.echo' => ['function' => function($methodName, $params) { /* ... */ }],
];

// Create the server instance
$server = new Server($my_methods, false);

// Handle the request and send the response
// When running from a web server, this will process the POST request
// When running from CLI for testing, you might need to simulate a request.
// For a simple web server setup, just ensuring 'server.php' is accessible via POST is enough.
// For testing, one could simulate $_SERVER['REQUEST_METHOD'] = 'POST' and php://input
// In a real scenario, $server->service() would be called directly in a web context.

// To run this server: Place 'server.php' in your web server's root, then make a POST request to it.
// Example for a real web environment (e.g., Apache/Nginx + PHP-FPM):
// If this file is server.php, navigate to http://localhost/server.php with an XML-RPC POST request.
// For demonstration, we'll assume it's set up to respond to an XML-RPC client.

echo "XML-RPC Server is running (waiting for POST requests). Please access this file via a web server.\n";
// Uncomment the line below to actually process requests in a web environment:
// $server->service();


// --- XML-RPC Client Example ---
// Save this as 'client.php'

// Assuming the server.php above is accessible at http://localhost/server.php
$server_url = 'http://localhost/server.php'; 

// Create an XML-RPC client instance
// The client expects the full URL to the server script.
$client = new Client($server_url);

// Optional: Set a timeout (in seconds)
$client->setTimeout(5);

// Create an XML-RPC request message
// Method name 'sample.add' and parameters
$message = new Request('sample.add',
    [
        new Value(10, Value::TYPE_INT), // First parameter
        new Value(25, Value::TYPE_INT)  // Second parameter
    ]
);

echo "\n--- XML-RPC Client Attempting to Call Server ---\n";

// Send the request and get the response
// Note: This requires the server.php to be running and accessible via HTTP
$response = $client->send($message);

if ($response->faultCode()) {
    echo 'XML-RPC Fault: ' . $response->faultString() . ' (Code: ' . $response->faultCode() . ")\n";
} else {
    $result = $response->value()->scalarval();
    echo 'XML-RPC Call Successful! Result: ' . $result . "\n";
}

// Example with an invalid call (not enough parameters)
$message_invalid = new Request('sample.add',
    [
        new Value(5, Value::TYPE_INT)
    ]
);

echo "\n--- XML-RPC Client Attempting Invalid Call ---\n";
$response_invalid = $client->send($message_invalid);

if ($response_invalid->faultCode()) {
    echo 'XML-RPC Fault: ' . $response_invalid->faultString() . ' (Code: ' . $response_invalid->faultCode() . ")\n";
} else {
    echo 'XML-RPC Call Successful (unexpected for invalid call)! Result: ' . $response_invalid->value()->scalarval() . "\n";
}

?>
```