Codeigniter cron job from CLI throws memcached errors - php

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().

Related

PHP CLI corrupts executed file

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.

Laravel8 laravelcollective/remote can I create a dynamic connection

I'm migrating our inhouse backup app onto Laravel8, so far so good. I'm interested in using the laravelcollective/remote facade (SSH) to ssh onto the remote server and run some commands which it looks like this would be very good at (rather than using php exec() methods the current backup app uses).
My question however is, can i build an array/object from the database and use these details as a connection without having to manually maintain the config/remote.php file? Maintaining this with any server changes will be a nightmare to maintain as we frequently update users and sites are added removed on a regular basis! any ideas? As mentioned we are storing the ssh creds in the database which is populated via a connection form within the app.
I've built a simple test function in a controller and stepped into this with my debugger. I expected to see the array/object which is created from the config/remote file and was planning to just add new items but i couldn't find any array/objects containing the default empty production config set as default in the config/remote.php file.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use SSH;
class SecureServerController extends Controller
{
public function test() {
SSH::into()->run([
'cd /var/www',
'git pull origin master'
], function($line)
{
echo $line.PHP_EOL;
});
}
}
The following is the route used:
use App\Http\Controllers\SecureServerController;
Route::get('/test', [SecureServerController::class, 'test']);
thanks
*** EDIT ***
SO I had a look at the code for the SSH facade and found I could create a config file and pass this via the connect function:
$config = [
'host' => '123.123.123.123',
'username' => 'the-user',
'password' => 'a-password'
];
SSH::connect($config)->run([
'cd /var/www',
'git pull origin master'
], function($line)
{
echo $line.PHP_EOL;
});
However i see no way to use any port except 22. almost all our servers use a non default port as an additional level of obfuscation.

Laravel 6.18.2: The Process class relies on proc_open, which is not available on your PHP installation

I used cron job to do some CRUD operation using laravel Task Scheduling. On localhost it is working fine. But on my shared host I keep getting this error.
2020-04-08 16:56:01] local.ERROR: The Process class relies on proc_open, which is not available on your PHP installation. {"exception":"[object] (Symfony\\Component\\Process\\Exception\\LogicException(code: 0): The Process class relies on proc_open, which is not available on your PHP installation. at /home/deshiit/public_html/bangladesh-railway-server/vendor/symfony/process/Process.php:143)
[stacktrace]
But on localhost it works fine. I contacted my hosting company to remove proc_open form disable PHP functions, but they can't. I tried the solution given here. But this solution is not working.
My PHP version is ea-php73. I also tried ea-php71 and ea-php72.
In
app/Console/Kernel.php
if I add
->withoutOverlapping(); after my command,
protected function schedule(Schedule $schedule)
{
    Log::info('Cron Job Started 1.1');
    $schedule->command('outlier:data')
    ->everyMinute()
    ->withoutOverlapping();
}
then proc_open error gives only for one time and then
protected function schedule(Schedule $schedule)
is getting called every minute but it is not executing the handle() funtion
public function handle()
{
Log::info('Cron Job Started 2.1 in Commands/FindOutlier.php');
}
But if I Clear Cache, again it gives the proc_open error for one time and then call the schedule funtion every minute.
As per the commentd above, make sure Flare does not collect git information (It will try to open the git process and get branch and tag information).
In flare.php (config/flare.php):
'collect_git_information' => false
'reporting' => [
'anonymize_ips' => true,
'collect_git_information' => false,
'report_queries' => true,
'maximum_number_of_collected_queries' => 200,
'report_query_bindings' => true,
'report_view_data' => true,
],
Now, this fixed it on my cPanel instance only after I cleared the config and route caching. Make sure you don't have anything cached and your OPCache is also cleared.
From what I see when I look at the code, Flare is the only library that calls upon proc_open. If this still doesn't work, try disabling debug mode.
on cPanel goto multiPhPINI and enableing (allow_url_fopen)
this may fix problem

How to get pthreads working in PHP?

I am using wampserver to test & run wordpress code in my local computer. In order to run pthread, I have followed the following steps:
1) I got the pthread zip file from http://windows.php.net/downloads/pecl/releases/pthreads/0.44/
(My machine has php 5.3.13 and downloaded the php_pthreads-0.44-5.3-ts-vc9-x86.zip file from the above link).
2) Extracted the zip file. Moved the php_pthreads.dll to the C:\wamp\bin\php\php5.3.13\ext directory.
3) Moved pthreadVC2.dll to the C:\wamp\bin\php\php5.3.13 directory.
4) Then Opened C:\wamp\bin\php\php5.3.13\php.ini and added the code extension=php_pthreads.dll at the begining of the file.
But when I try to run the following code:
<?php
class My extends Thread {
public function run() {
printf("%s is Thread #%lu\n", __CLASS__, $this->getThreadId());
}
}
$my = new My();
$my->start();
?>
It gives me the following error:
Fatal error: Class 'Thread' not found in C:\wamp\www\wp-admin\includes\post.php on line 2
Can you please tell me how to install pthreads in my computer to use with php? and do I have to install any other software?
I've noticed that wampserver has php.ini in two separate places. One place is in the /wamp/bin/php/php5... directory, and the other place is in the /wamp/bin/apache/apache.../bin directory (where "..." represents version numbers). The two files need to be identical, because apparently both are loaded at different times by the overall wampserver boot-up procedure.
(Note I only discovered this recently, and may be well "behind the curve" of doing fancy things with wampserver --maybe everyone else has been dealing with both files for a long time. So I don't know if this simple thing will fix your problem; I came here looking for info, myself, regarding doing some multi-threading stuff. :)
One other thing. According to this page: www.php.net/manual/en/pthreads.requirements.php
PHP has to be compiled with "--enable-zts" in order for pthreads stuff to work. I have not been able to find any evidence that the PHP part of wampserver was compiled that way.
(months later)
Having decided I didn't really immediately need to do any threading stuff, I went on to do other things, until the need actually arose. I now can say that the version of PHP compiled into WampServer does support the "pthread" extension, although some set-up work is needed, first. The instructions I saw mentioned putting a couple of .dll files (after a download and unZip) into certain places, but that didn't work for me. Copying them to the \Windows\System32 directory did work. (Putting them into the \apache...\bin directory also works; there are some other php .dll files in there.)
After that, much like what you did, it is necessary to define a "class" that extends the "Thread" class, in order to actually do something in another thread. The "run()" function in the Thread class is "abstract", and needs to be "realized" as an actual function in the extended class. Then the "new" operator can create an "instance", an object of that specified class, for actual use. Here's the class that I needed:
//Purpose: Use another thread to run the code in another php file, after a delay
class xT extends Thread
{ var $fil, $tim;
function savWhatWhen($f="", $t=0)
{ $this->fil = $f; //save What, file to process
$this->tim = $t; //save When, delay before processing file
return;
}
function run()
{ ini_set('max_execution_time', 600); //600 seconds = 10 minutes
sleep($this->tim); //do a delay; beware of max-exec-time!
include($this->fil); //load file-to-process, and process it
return;
} }
That "savWhatWhen()" function was created specifically for this extension of the basic Thread class. Here's some code for using that class:
$TH = new xT(); //prepare a separate Thread
$TH->savWhatWhen("d:/wamp/myscripts/test.php", 45);//file-name and delay time
$TH->start(); //after delay, process file
//the code that does this can terminate, while OTHER thread is doing a delay
Note for anyone copying this code, you might need to make sure your "open_basedir" setting in the php.ini allows access to the specified file.
More months later: With lots of things being worked on, I haven't put a lot of time into using my pthread object. I did encounter a peculiarity that makes me wonder about whether or not I can actually use pthreads the way I had hoped. Here is what I have observed:
1. An initial php file is called by AJAX, to do something.
2. The PHP processor on the Web Server does that thing.
3. Various data is supposed to be echoed to the browser.
4. The initial php file calls for the creation of another thread, and terminates.
5. The browser does not yet receive the echoed data!
6. The PHP processor on the Web Server does the work delegated to the second thread.
7. When the second thread terminates, NOW the browser receives the echoed data!
At this writing I'm thinking I missed something. Perhaps I need to do some forceful "flush" stuff when the first thread ends, so that the browser can receive the echoed data and the user can do things while the PHP processor on the server is also doing things.
Check for extension_dir = "ext" in you php.ini file. Make sure it points to the folder where your extensions reside and make sure it's not commented (it has a semicolon ; in front of it)
You have to add a require_once() with the path of the Thread class before extending it (if your framework don't use an autoload class system)
I've encountered the same problem, in my case placing the pthreadVC2.dll in
..wamp\bin\apache\Apache2.4.4\bin
(instead of ..\wamp\bin\php\php5.4.16 as the guide in php.net instructs) solved the problem
Wamp server has a separate php.ini config file for the browser and for the cli.
To use the pthreads module in the browser with WAMP Server you need to copy the "pthreadVC2.dll" into the apache "bin" directory also.
You should now have he "pthreadVC2.dll" in both of these folders (if installed in default location):
C:\wamp\bin\php\php[x.x.xx]\bin
C:\wamp\bin\apache\apache[x.x.x]\bin
You will also need to update the php.ini file within the php bin directory AND the apache bin directory to include:
extension=php_pthreads.dll
This now means you can use pthreads in the browser and in the cli with wamp server
After encountering the same problem, I noticed that I have installed the wrong Pthread version (3.1.6 : requires PHP7+) which wasn't compatible with my PHP version (5.5.12). Solved the problem with Pthread version 0.0.44. An earlier version should probably work well.
Here is the download page for Pthread and the installation page. Be careful about the both php.ini location as mentioned above (Apache folder=for Browser, PHP folder=CLI).

Temporarily disable cURL for testing purposes

I am writing a class that detects whether cURL is available, does one thing if it is, and another if it isn't. I therefore need to know how to disable cURL temporarily to test this class. I do not want to change the PHP INI file. Any ideas much appreciated.
Just wondering, Im writing an alternative for if cURL is unavailble, how likely is this? Am I wasting my time. Is cURL usually available?
Curl is enabled / disabled in your php.ini. You can't enable and disable it any other way.
Open php.ini find the below and put a semi colon before it to comment it out:
extension=php_curl.dll
AFAIK there is no way to do this at run time, because modules are loaded during PHP startup, before any of you code is executed. The only way to do it is by disabling (or rather, not enabling) an extension in php.ini. You probably can't even do that with cURL, as it will probably be compiled in, not dynamically loaded.
Having said that - why not just change the check to test your "if not available" code - presumably you have a block something like this:
if (curl_exists()) { //obviously there is no such function, but you must have some condition that determines this
// Do stuff using curl
} else {
// Do something horrible
}
well, just change it to this temporarily:
if (!curl_exists()) {
// etc etc
I think the best option is to change your detection script to allow disabling it with a manual configuration.
You cannot disable function on the fly. You need to change php.ini for that.
http://www.php.net/manual/en/function.dl.php
dl — Loads a PHP extension at runtime
bool dl ( string $library )
Loads the PHP extension given by the parameter library.
Use extension_loaded() to test whether a given extension is already available or not. This works on both built-in extensions and dynamically loaded ones (either through php.ini or dl()).
Warning:
This function has been removed from some SAPI's in PHP 5.3.
<?php
// Example loading an extension based on OS
if (!extension_loaded('sqlite')) {
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
dl('php_sqlite.dll');
} else {
dl('sqlite.so');
}
}
//this deals with sqlite but would be easy to figure out how to use it for cURL :)
?>
So you can comment out the loading of cURL extension in php.ini and then "dynamically load" it when needed.
HTH
probably the easiest way is by open file curl.ini, Im use ubuntu 12.04 and file located at
/etc/php5/apache2/conf.d/curl.ini
leave a comment by adding semicolon before extension=curl.so
You can see the location of curl.ini through phpinfo ();
dont forget to restart the Apache
sudo service apache2 restart
Curl is available as long its extension is loaded (which is mostly by default).
You can check what curl extension provides by the following command:
php --re curl
which gives you list of functions, classes and its methods.
To temporary disable curl extension, you can run PHP with -n to simply ignore your php.ini, for example:
$ php -n -r "print_r(curl_version());"
Fatal error: Call to undefined function curl_version() in Command line code on line 1
Here is working example:
$ php -r "print_r(curl_version());"
Array
(
[version_number] => 463623
...

Categories