PHP CLI corrupts executed file - php

Problem description
Sometimes after running PHP CLI, the primary executed PHP file is erased. It's simply gone.
The file is missing / corrupted. Undelete (Netbeans History - revert delete) still shows the file, but it is not possible to recover it. It is also not possible to replace / reinstate the file with the identical filename.
Trial and error attempts
The issue occurs on (3) different computers, all Windows 10 or Windows 11.
I've used different versions of PHP (php-7.3.10-Win32-VC15-x64, php-8.1.4-Win32-vs16-x64).
The code is not doing any file IO at all. It uses a React event loop, listening to a websocket - "server_worklistobserver.php":
<?php
require __DIR__ . '/vendor/autoload.php';
$context = array(
'tls' => array(
'local_cert' => "certificate.crt",
'local_pk' => "certificate.key",
'allow_self_signed' => true, // Set to false in production
'verify_peer' => false
)
);
// Set up websocket server
$loop = React\EventLoop\Factory::create();
$application = new Ratchet\App('my.domain.com', 8443, 'tls://0.0.0.0', $loop, $context);
// Set up controller component
$controller = new WorklistObserver();
$application->route('/checkworklist', $controller, array('*'));
$application->run();
die('-server stopped-');
The disappearance happens when the PHP execution is cancelled. Either by Ctrl-Break, or when run as a service, a service stop/restart.
Execution is started by: php.exe server_worklistobserver.php in a dos-box (cmd).
Using administrator permissions has no effect. Performing a harddisk scan has no effect; there are no issues found. The issue is rather persistent, but not regular; it seems to happen by chance.
Associated PHP files are left intact.
The issue has never occurred on the Apache driven PHP execution.
Please help
What could I do different? Does have anyone have a similar experience? I can't find anything alike on the internet...
Thanks in advance.

Thanks so much, Chris! Indeed, I found the entries in the quarantaine of my virusscanner. I've added an exception rule and don't expect to have this happen again.

Related

Handling expiring Let's Encyrpt SSL in a websocket server with Ratchet PHP

After reading practically every article on the subject of getting the Ratchet PHP implementation of Websockets to work with SSL, I finally got it working with the help of many tips, although mainly the info here https://github.com/ratchetphp/Ratchet/issues/489 which basically modifies the way you create the IoServer to use React's Secure Server. My implementation at the server end in PHP like so:
$loop = \React\EventLoop\Factory::create();
$secure_websockets = new \React\Socket\Server('0.0.0.0:8080', $loop);
$secure_websockets = new \React\Socket\SecureServer($secure_websockets, $loop, [
'local_cert' => '/path/to/letsencyrpt/cert.crt',
'local_pk' => '/path/to/letsencyrpt/key.key',
'verify_peer' => false
]);
$app = new \Ratchet\Http\HttpServer(
new \Ratchet\WebSocket\WsServer(
new Chat()
)
);
$server = new \Ratchet\Server\IoServer($app, $secure_websockets, $loop);
$server->run();
And on the client side the Javascript:
function startWebsocket() {
var conn = new WebSocket('wss://domain.com:port');
conn.onopen = function(e) {
console.log("Connection established!");
};
}
startWebsocket();
And that works just fine.
BUT... I'm using Let's Encrypt certificates on the server and they have a rather short lifetime. That's fine on https as the host (Siteground) automatically renews the SSL before expiry, but if I'm putting a path to a specific Cert/Key pair (as above), they will expire.
So, are my options:
A: Put a repeating note in my calendar to remind me to update the Cert/Key paths every 3 months and live with it, or..
B: Is there a way to discover the current Cert/Key pair and drop that in as a variable?
Some things to bear in mind:
I'm on Siteground with a Cloud Server, but not with root access (I stupidly signed up for 'Geeky Features' years ago before my techy knowledge improved enough for me to need root).
Whilst I don't have root, it is effectively a dedicated server, so I can ask Siteground's support guys to change things for me - but I'd really need to be very specific with any requests. Trying things out is probably not an option here.
I explored the other method of getting wss: working with Ratchet, namely Proxying the https request over to the ws port. Didn't get very far with that since the version of Apache installed doesn't seem to be recent enough to support the tunnel and although there are references to NGINX running in parallel to Apache on Siteground, I just kept getting error any time I tried to use it to proxy. Didn't help that without root access I'm pretty limited in what I can do.

XMPP (XMPPHP) session won't start

Fellows I'm working in a new server and, at first, it looks all good. The eJabberd webadmin runs OK and I was able to even create an user by that interface.
The situation is, the same application that usually ran on my previous server freezes at the waiting for the session to start, the code:
$this->lnk->processUntil('session_start');
The $this->lnk->connect(); works fine but it seems that the session can't be set. Any suggestions for where or what I should go take a look first?
ACKs:
The XMPP application has been set the same way than was in the older server.
Here is the whole code:
$this->lnk = new XMPPHP_XMPP($this->config['host'],
$this->config['port'],
$this->config['username'],
$this->config['password'],
$this->config['service'],
$this->config['domain'],
$printlog = false,
$loglevel = XMPPHP_Log::LEVEL_VERBOSE);
$this->lnk->useEncryption(true);
$this->lnk->connect();
$this->lnk->processUntil('session_start');
The issue was caused by $this->lnk->useEncryption(true);. Since my new server hadn't proper SSL/TLS settings, this line caused the freezing of the code.
Possible solvings are disabling encryption and adjusting you SSL/TLS credentials.

Problems with PHP Soap Server caching response

I've successfully created a client and server soap object... but having real problems with what I think is caching on the server side. I'm disabling all caching on both client and server scripts with:
ini_set("soap.wsdl_cache", "0");
ini_set("soap.wsdl_cache_ttl", "0");
ini_set("soap.wsdl_cache_enabled", "0");
But I seem to get exactly the same response from the server no matter what I do. I've changed the object names, changed the WSDL name and even appended a timestamp to the object names to make sure it's never the same each call. Then suddenly, after about 10 or 20 minutes or so it will update and I'll get a different response. I've checked phpinfo() and it says the caching ttl is a day long (globally), so I think it's definitely shorter than that.
Any ideas about killing off any kind of caching?
You can try passing the options to SOAP objects:
$client = new SoapClient("some.wsdl", array('cache_wsdl' => WSDL_CACHE_NONE));
$server = new SoapServer("some.wsdl", array('cache_wsdl' => WSDL_CACHE_NONE));
If this does not help, try to clear the wsdl cache file. On linux, it's usually in /tmp folder and it's name starts with wsdl-. If clearing this file does not help, maybe some other cache is used? Is it just SoapServer or are some additional libs used?
I had the same issue, and trying to set:
new SoapClient("some.wsdl", array('cache_wsdl' => WSDL_CACHE_NONE))
did nothing.
In the end, I located the /tmp folder the server used to cache the wsdl file and just delete it. Fixed!
The /tmp folder was not in my virtual domain /tmp folder, but at the root of the server directory.

Codeigniter cron job from CLI throws memcached errors

I'm trying to set up the cron jobs for my Codigniter application, however when I run the cron, it throws me memcached errors:
PHP Fatal error: Call to a member function get() on a non-object in /var/www/domain.com/www/dev/system/libraries/Cache/drivers/Cache_memcached.php on line 50
Fatal error: Call to a member function get() on a non-object in /var/www/domain.com/www/dev/system/libraries/Cache/drivers/Cache_memcached.php on line 50
Although I have no idea why this is throwing all the time, I can't find any errors in my cron job file, nor how to solve this problem because I don't know where this is being called, I looked into my autoloaded libraries and helpers, none of them seem to be wrong.
I also can confirm that memcached is installed, if I visit my site, memcached indeed works.
I tried suppressing the get() in Cached_memcached.php with a #, but this didn't help because no output is shown (but there is supposed to be output shown).
The command I run for the cron (user: www-data) is:
/usr/bin/php -q /var/www/domain.com/www/dev/index.php cron run cron
I'm running Ubuntu 11.10 x86_64.
This is my cron file:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Cron extends CI_Controller {
var $current_cron_tasks = array('cron');
public function run($mode)
{
if($this->input->is_cli_request())
{
if(isset($mode) || !empty($mode))
{
if(in_array($mode, $this->current_cron_tasks))
{
$this->benchmark->mark('cron_start');
if($mode == 'cron')
{
if($this->cache->memcached->get('currency_cache'))
{
if($this->cache->memcached->delete('currency_cache'))
{
$this->load->library('convert');
$this->convert->get_cache(true);
}
}
echo $mode . ' executed successfully';
}
$this->benchmark->mark('cron_end');
$elapsed_time = $this->benchmark->elapsed_time('cron_start', 'cron_end');
echo $elapsed_time;
}
}
}
}
}
The first thing to try would be the following to determine if memcached is supported.
var_dump($this->cache->memcached->is_supported());
The second thing to ensure is that you've got a memcached.php file in application/config/
It should contain a multidimensional array of memcached hosts with the following keys:
host
port
weight
The following example defines two servers. The array keys server_1 and server_2 are irrelevant, they can be named however.
$config = array(
'server_1' => array(
'host' => '127.0.0.1',
'port' => 11211,
'weight' => 1
),
'server_2' => array(
'host' => '127.0.0.2',
'port' => 11211,
'weight' => 1
)
);
The next thing I'd try is check to see if the controller can be run in the web browser as opposed to the CLI or if you get the same error.
Also, explicitly loading the memcached driver might be worthwhile trying. The following will load the memcached driver, and failing that call upon the file cache driver.
$this->load->driver('cache', array('adapter' => 'memcached', 'backup' => 'file'));
Using this method allows you to call $this->cache->get(); to take into account the fallback too.
Another thing to check is that you're not using separate php.ini files for web and CLI.
On Ubuntu it's located in
/etc/php5/cli/php.ini
And you should ensure that the following line is present, and not commented out
extension=memcache.so
Alternatively, you can create a file /etc/php5/cond.d/memcache.ini with the same contents.
Don't forget to restart services after changing configuration files.
You can check memcached is indeed set up correctly using the CLI by executing the following
php -i | grep memcache
The problem is that $this->cache->memcached is NULL (or otherwise uninitialized), meaning that the cache hasn't been initialized.
An easy fix would be to simply create the memcache object yourself. The proper fix, however, would be to look through the source and trace how the memcache object normally gets instantiated (look for new Memcache and set a debug_print_backtrace() there. Trace the debug stack back and compare it with what your cron does - look where it goes wrong then correct it). This is basic debugging btw, sorry.
Also, make sure you do load the drivers. If your cron uses a different bootstrap function than your normal index (never used CI, is that even possible?) then make sure that the memcache init is placed in the right location.
-edit-
$this->cache->memcached probably isn't actually NULL, but the actual connection to the Memcache server definitely wasn't made before you started calling get().

Detecting no available server with PHP and Gearman

I'm currently making use of Gearman with PHP using the standard bindings (docs here). All functioning fine, but I have one small issue with not being able to detect when a call to GearmanClient::addServer (docs here) is "successfull", by which I mean...
The issue is that adding the server attempts no socket I/O, meaning that the server may not actually exist or be operational. This means that subsequent code calls (in the scenario where the sever does not infact exist) fail and result in PHP warnings
Is there any way, or what is the best way, to confirm that the Gearman Daemon is operational on the server before or after adding it?
I would like to achieve this so that I can reliably handle scenarios in which Gearman may have died, or the server is un-contactable perhaps..
Many thanks.
We first tried this by manually calling fsockopen on the host and port passed to addServer, but it turns out that this can leave a lot of hanging connections as the Gearman server expects something to happen over that socket.
We use a monitor script to check the status of the daemon and its workers — something similar to this perl script on Google Groups. We modified the script to restart the daemon if it was not running.
If this does not appeal, have a look at the Gearman Protocol (specifically the “Administrative Protocol” section, referenced in the above thread) and use the status command. This will give you information on the status of the jobs and workers, but also means you can perform a socket connection to the daemon and not leave it hanging.
You can use this library: https://github.com/necromant2005/gearman-stats
It has no external dependencies.
$adapter = new \TweeGearmanStat\Queue\Gearman(array(
'h1' => array('host' => '10.0.0.1', 'port' => 4730, 'timeout' => 1),
'h2' => array('host' => '10.0.0.2', 'port' => 4730, 'timeout' => 1),
));
$status = $adapter->status();
var_dump($status);

Categories