How do you run raw redis commands in PHP? - php

I have been using predis to try to figure out how to run raw redis commands, but I am having trouble. The documentation for predis is extremely outdated. It says that there is a method called "rawCommand()" which will allow a user to run raw Redis commands, but I found a changelog that says it is no longer supported:
https://github.com/nrk/predis/blame/master/CHANGELOG
Does anyone have any hints of how I can run raw redis commands?

Here you go. This has worked perfectly for me, and I did not know it even had that function
$cmdSet = $redis->createCommand('set');
$cmdSet->setArgumentsArray(array('library', 'predis'));
$cmdSetReply = $redis->executeCommand($cmdSet);
He has a wiki page on this. Look for sending commands.

I'm actually guessing here, but let's pretend for a while I did not say that aloud.
Check out the function writeCommand() in lib/Predis/Network/StreamConnection.php on line 176 and use it through SimpleDebuggableConnection in examples/SimpleDebuggableConnection.php. You still have to define new commands that are not already defined in lib/predis/commands, as mentioned in the wiki that #Colum referred to.
If you're really feeling adventurous, change the protected method writeBytes() in StreamConnection on line 96 to public. That should enable you to feed it pure redis with
$redis->getConnection()->writeBytes("*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n")
Unfortunately, publicizing the writeBytes() seems to go in to the direction of http://en.wikipedia.org/wiki/Object_orgy anti-pattern.
Good luck!

It's easy!
Take this class: RedisServer
and write:
$redis = new \Jamm\Memory\RedisServer();
$redis->send_command('set','key',5); //here any raw command

PHPRedis
on phpredis extension you can use following:
$redis->rawCommand("count", "a:", 10, "a:");
PRedis
on phpredis you can use following:
$redis->executeRaw(["count", "a:", 10, "a:"]);
PRedis - more complicated way
on predis you can do like this:
<?php
require 'Predis/Autoloader.php';
Predis\Autoloader::register();
class PRredisCOUNT extends Predis\Command\Command {
function getId(){
return 'COUNT';
}
}
class PRredisSUM extends Predis\Command\Command {
function getId(){
return 'SUM';
}
}
function registerHM4Commands($redis){
$redis->getProfile()->defineCommand("count" , "PRredisCOUNT" );
$redis->getProfile()->defineCommand("sum" , "PRredisSUM" );
}
$redis = new Predis\Client("127.0.0.1:2000");
registerHM4Commands($redis);
// after that you can do:
$redis->count($key, $page, $prefix);

Related

How to test semaphores with PHPUnit

I'm using The Symfony Lock package to check if a class method can be executed
if ($this->lock->acquire()) {
$this->execute();
$this->lock->release();
}
Important: I'm not using the Symfony Framework, only the Lock component
I want to make a test that asserts that the execution is locked when running in multiple threads, but I have not found any documentation on how to achieve this.
Is it a good idea to use pthreads? If not, which is the best way to make this test?
Thank you very much.
Referring to the Lock Component documentation :
https://symfony.com/doc/current/components/lock.html#usage
Information on the CommandTester :
https://symfony.com/doc/current/console.html#testing-commands
Solution for PHPUnit test :
use Symfony\Component\Lock\Factory;
use Symfony\Component\Lock\Store\SemaphoreStore;
public function testLockIsSet()
{
// Create a new Semaphore lock with the same ID as the one that would be
// created if you were running the command / class / process etc.
$store = new SemaphoreStore();
$factory = new Factory($store);
$lock = $factory->createLock('lock-name-used-eg-generate-pdf');
if ($lock->acquire()) {
// In my use case I was running multiple commands to see if the lock
// was working properly
$commandTester = new CommandTester($this->command);
// Try and run the command. The lock should already be set.
$commandTester->execute(
[
'command' => $this->command->getName()
]
);
// You could also use expectException() here for LogicException
$this->assertContains(
'The command is already running in locked mode.',
$commandTester->getDisplay()
);
$lock->release();
}
}

Symfony2 command within an asynchronous subprocess

I am new on Symfony2 and I got blocked when trying to run an asynchronous command like this:
class MyCommand extends ContainerAwareCommand{
protected function configure()
{
$this
->setName('my:command')
->setDescription('My command')
->addArgument(
'country',
InputArgument::REQUIRED,
'Which country?'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$country = $input->getArgument('country');
// Obtain the doctrine manager
$dm = $this->getContainer()->get('doctrine_mongodb.odm.document_manager');
$users = $dm->getRepository('MyBundle:User')
->findBy( array('country'=>$country));
}}
That works perfectly when I call it from my command line:
php app/console my:command uk
But it doesn't work when I call it trowh a Symfony2 Process:
$process = new Process("php ../app/console my:command $country");
$process->start();
I get a database error: "[MongoWriteConcernException] 127.0.0.1:27017: not master"
I think that means that the process is not getting my database configuration...
I just want to run an asynchronous process, is there other way to do it?
Maybe a way to call the Application Command that do not require the answer to keep going ?
Maybe I need to use injection?
PS: My current command is just a test, at the end it should be an 'expensive' operation...
Well, I found out what happened...
I use multiple environments: DEV, TEST and PROD.
And I also use differents servers.
So the DEV environment is my own machine with a simple mongodb configuration.
But the TEST environment is on other server with a replica set configuration...
Now the error get full sense: "[MongoWriteConcernException] 127.0.0.1:27017: not master"
To solve it, I've just added the environment parameter (--env=) to the process and everything worked like a charm:
$process = new Process("php ../app/console my:command $country --env=test");
Actually, to get the correct environment I use this:
$this->get('kernel')->getEnvironment();
Which let's my code as follows:
$process = new Process("php ../app/console my:command $country --env=".$this->get('kernel')->getEnvironment());
Maybe is not a beautifull way to do it, but it works for me :)
Disclamer: This might be a bit overkill for what you're trying to do :)
I would choose an opposite way to do it: pthreads
First, quick examination of StackOverflow showed me a really nice example of using pthreads: Multi-threading is possible in php
Then, knowing that you could invoke your command from another command:
http://www.craftitonline.com/2011/06/calling-commands-within-commands-in-symfony2/
... lets you piece all the parts. It's a bit complicated but it does the job.
In case you want to execute your code completely async in Symfony2/3 there is AsyncServiceCallBundle for that.
You should just call it like this:
$this->get('krlove.async')->call('your_service_id', 'method_name', [$arg1, $arg2]);
Internally it uses this approach to run your code in background.

PHP-FFMpeg prerequisites

I'm attempting to implement https://github.com/PHP-FFMpeg/PHP-FFMpeg
I copied the src/FFMpeg folder to my includes folder and made sure my autoloader knows where to find everything.
as a test I made a script that simply does:
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
I get:
Fatal error: Class 'Doctrine\Common\Cache\ArrayCache' not found in /var/www/php/include/FFMpeg/FFProbe.php on line 203
My question is: does PHP-FFMPeg require Doctrine, because that is not stated in the documentation. What version do I need? Are there other prerequisites?
I could create a new question for this, but I'm not sure if I should. I now have PHP-ffmpeg implemented. I'm using Laravel, however that should be irrelevant for this question. I'm trying to enable progress monitoring. It works, however I need to pass in an ID so I can update the correct key in memcache.
$id = 12345;
$format->on('progress', function ($audio, $format, $percentage) {
//this works perfect, but doesn't tell me which item is being updated
Cache::put("progress", $percentage, .25);
//this does not work as I am unable to pass in $id, if I add it as the 4th argument above it will display the number of threads or something
//Cache::put("{$id}_progress", $percentage, .25);
});
I need clarification on the "on" method. I looked through https://ffmpeg-php.readthedocs.org/en/latest/_static/API/ and was not able to figure out how this method works. Any help would be appreciated.
You should follow the recommended instructions in the README.
Composer is the easiest way to install PHP-FFMpeg dependencies
The "on" method called on the format is an implementation of EventEmitter.
As you can see here : https://ffmpeg-php.readthedocs.org/en/latest/_static/API/FFMpeg/Format/ProgressableInterface.html it extends the EventEmitterInterface of https://github.com/igorw/evenement.
If you're really interested about how it works under the hood, have a look at here :
The progress listener is created here : https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Format/Audio/DefaultAudio.php#L96 and added at execution here https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Media/Video.php#L151
This is actually possible because FFMpegDriver extends the Driver provided by https://github.com/alchemy-fr/BinaryDriver
Hope this helps :)

Is there an alternative to the "filter_var" function in php when using HHVM?

I have been recently playing around with HHVM. Went through a lot of trouble getting it to work on my computer. I know that not all PHP functions are available. As a test, I am writing a new website using it instead of using my current code. I ran into a problem when trying to use
filter_var($var,FILTER_SANITIZE_URL);
From the error.log file, it turns out that this function is undefined. Is the filter_var function not available for use in HHVM or am I just doing something wrong here. I like to keep things DRY, this would mean I have to do a lot more validation than I expected.
filter_var is now implemented in hhvm. Open github issues if you have any problems with it.
This function appears to not have been implemented on HHVM See http://comments.gmane.org/gmane.science.linguistics.wikipedia.technical/70038
An option if you want to rely on this functionality with the hopes that it will enter the fold is to polyfill it in (partial implementation to inspire the motivated).
if (!function_exists("filter_var")){
// define the constants used by the function
define("FILTER_VALIDATE_EMAIL", "email");
function filter_var(){
$args = func_get_args();
// $args[1] is the filter type (second parameter)
switch ($args[1]){
case FILTER_VALIDATE_EMAIL:
if (preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $args[0])?$args[0]:false;
break;
}
}
}

How can I detect, using php, if the machine has oracle (oci8 and/or pdo_oci) installed?

How can I detect, using php, if the machine has oracle (oci8 and/or pdo_oci) installed?
I'm working on a PHP project where some developers, such as myself, have it installed, but there's little need for the themers to have it. How can I write a quick function to use in the code so that my themers are able to work on the look of the site without having it crash on them?
if the oci extension isn't installed, then you'll get a fatal error with farside.myopenid.com's answer, you can use function_exists('oci_connect') or extension_loaded('oci8') (or whatever the extension's actually called)
The folks here have pieces of the solution, but let's roll it all into one solution.
For just a single instance of an oracle function, testing with function_exists() is good enough; but if the code is sprinkled throughout to OCI calls, it's going to be a huge pain in the ass to wrap every one in a function_exists() test.
Therefore, I think the simplest solution would be to create a file called nodatabase.php that might look something like this:
<?php
// nodatabase.php
// explicitly override database functions with empty stubs. Only include this file
// when you want to run the code without an actual database backend. Any database-
// related functions used in the codebase must be included below.
function oci_connect($user, $password, $db = '', $charset='UTF-8', $session_mode=null)
{
}
function oci_execute($statement, $mode=0)
{
}
// and so on...
Then, conditionally include this file if a global (say, THEME_TESTING) is defined just ahead of where the database code is called. Such an include might look like this:
// define("THEME_TESTING", true) // uncomment this line to disable database usage
if( defined(THEME_TESTING) )
include('nodatabase.php'); // override oracle API with stub functions for the artists.
Now, when you hand the project over to the artists, they simply need to make that one modification and they're good to go.
I dont know if I fully understand your question but a simple way would be to do this:
<?php
$connection = oci_connect('username', 'password', 'table');
if (!$connection) {
// no OCI connection.
}
?>
As mentioned above by Greg, programmatically you can use the function_exists() method. Don't forget you can also use the following to see all the environment specifics with your PHP install using the following:
<?php
phpinfo();
?>

Categories