Reputation: 1685
I have a single PHP class, which can communicate with an API we are developing. Rather than using different API versions and letting the user manually updating the PHP class script, I would like to make this process automatic.
This update has to be done on the fly, when an update has been found. This is my idea:
This obviously means that the PHP class needs write permissions to the file the class exists in, so it can simply overwrite the class with the new version.
But how can the old class now execute the requested API request through the new class version? In a perfect world, I'm looking for a way to do this without the use of eval(), as this function is blocked on many hosts.
To elaborate:
$myApi = new MyApi;
$myApi->registerCustomer($customerData);
The registerCustomer() function would do something like this:
if (classNotUpToDate) {
downloadNewClass();
registerCustomerthroughNewClass()
} else {
registerCustomerDo();
}
Now the only way I can think of to do this:
class MyApi {...
with class MyApiUpdate {..
$myApiUpdate = new MyApiUpdate;
registerCustomer()
function: $myApiUpdate->registerCustomer($customerData);
Is this the only way to achieve what I want without either creating a new file or using eval()? I don't think this is a very handsome method, so I'm looking for a cleaner way to achieve this.
Upvotes: 0
Views: 902
Reputation: 706
It can be done in simple steps, Below is working POC of the same. Below are the requirements
Example self updating class:
<?php
class MyClass
{
private $version;
public function __construct()
{
$this->version = 1.0;
}
public function checkForUpdates()
{
// Get the latest version number from a remote file
$latestVersion = file_get_contents('https://www.yourwebsite.com/version.txt');
// Compare the latest version to the current version
if ($latestVersion > $this->version) {
// Update the class code
$this->update();
}
}
private function update()
{
// Get the updated code from a remote file
$updatedCode = file_get_contents('https://www.yourwebsite.com/MyClass.txt');
// Overwrite the current class code with the updated code
file_put_contents(__FILE__, $updatedCode);
// Refresh the class definition
require_once __FILE__;
}
}
$obj = new MyClass();
$obj->checkForUpdates();
version.txt code
1.1
MyClass.txt code
<?php
class MyClass
{
private $version;
private $author;
public function __construct()
{
$this->version = 1.1;
$this->author = "Kapil";
}
public function checkForUpdates()
{
// Get the latest version number from a remote file
$latestVersion = file_get_contents('https://www.yourwebsite.com/version.txt');
// Compare the latest version to the current version
if ($latestVersion > $this->version) {
// Update the class code
$this->update();
}
}
private function update()
{
// Get the updated code from a remote file
$updatedCode = file_get_contents('https://www.yourwebsite.com/MyClass.txt');
// Overwrite the current class code with the updated code
file_put_contents(__FILE__, $updatedCode);
// Refresh the class definition
require_once __FILE__;
}
}
Upvotes: 0
Reputation: 8945
I would consider this approach to be rather profoundly unsafe, and therefore do not recommend it.
Instead, I recommend that your API should require an "API version" indicator be sent with each request: the client informs the server what API version it's using, and the server, in like manner, informs the client what version is responding to it.
Make the versions as "upward compatible" as possible. A newer version of the API can talk to an older version, and, because the two parties self-identify, you know exactly what requests each one can and cannot use. If you invent a new API-call that supersedes an older one, leave both of them in the implementation, even if you "stub out" one of them or have the implementation of the older call invoke the code of the newer one.
Different versions of the API can, if necessary and appropriate, be implemented using subclasses.
You should, as a matter of course, have test-suites for each API version, and you should verify that all of the older tests continue to run correctly against newer versions. That is to say, that there is no "regression."
But, no, no "automatic on-the-fly updates," and no writeable files. As they say: "Not only 'no,' but, 'hell, no!'"
Upvotes: 6