PHP - sem_get undefined runnin on linux CentOs - php

I'm having this error
Call to undefined function sem_get()
It is running on PHP Version 5.3.27, Apache/2.2.15 and CentOS.
I can't find a reason for this, also we have a testing server with (almost) the same setup and it is working fine (maybe different PHP extensions because we use this server with other projects too).
The test that I am running is the following:
<pre>
starts
<?
try {
echo "instance\n";
$mutex = new Mutex(633);
echo "Acquire \n";
$mutex->Acquire();
echo "\n\n Atomic magic \n\n";
echo "release \n";
$mutex->Release();
echo "null \n";
$mutex = null;
echo "end \n";
}
catch (Exception $e)
{
echo $e;
echo "\n<hr>\n";
var_dump(error_get_last());
}
And the class Mutex is the following:
<?php
class Mutex
{
protected $_Id;
protected $_SemId;
protected $_IsAcquired = false;
/**
* #param int $id Identifier of the Mutex, must be a number
*/
function __construct($id)
{
if (!is_int($id))
{
throw new Exception('The Mutex identifier must be a number');
}
$this->_Id = $id;
if (!($this->_SemId = sem_get($this->_Id, 1)))
{
throw new Exception('Error getting semaphore');
}
}
public function Acquire()
{
if (!sem_acquire($this->_SemId))
{
throw new Exception('Error acquiring semaphore');
}
$this->_IsAcquired = true;
}
public function Release()
{
if (!$this->_IsAcquired)
{
return;
}
if (!sem_release($this->_SemId))
{
throw new Exception('Error releasing semaphore');
}
$this->_IsAcquired = false;
}
}
?>
Thanks

Related

Some try catch issue with php

I'm trying to create a class for work with crontab in php.
I used this tutorial.
I've installed libssh2 but as you can see there is no work with it yet. So I have a file Ssh2_crontab_manager.php on my server. Here it's content:
<?php
Class Ssh2_crontab_manager
{
private $connection;
private $path;
private $handle;
private $cron_file;
function __construct($host=NULL, $port=NULL, $username=NULL, $password=NULL)
{
$path_length = strrpos(__FILE__, "/");
$this->path = substr(__FILE__, 0, $path_length) . '/';
$this->handle = 'crontab.txt';
$this->cron_file = "{$this->path}{$this->handle}";
/*try
{
if ((is_null($host)) || (is_null($port)) || (is_null($username)) || (is_null($password))) throw new Exception("Please specify the host, port, username and password!");
}
catch
{
}*/
}
}
?>
And here is noReplyCrontab.php where I try to use this class:
<?php
include './lib/Ssh2_crontab_manager.php';
//$crontab = new Ssh2_crontab_manager('host', '22', 'user', 'pass');
echo 'WORKS';
?>
If I run it now, it says 'works', but if I uncomment try/catch block it shows just white screen, so I suppose that there is some mistake. Any one can show it to me?
Your code says
catch
{
}
But catch What?
You have to provide that value to catch clause
catch (Exception $e)
{
//now it will work fine
}
Manual
try this
try
{
if (true) throw new Exception("Please specify the host, port, username and password!");
}
catch(Exception $e)
{
echo $e->getMessage();
}

php code like transaction in database?

I have certain code that I want to be run by only one user at a time. I don't want to make son complex lock/session relied system, I just wish to delay the users request our to return some message to try again.
The code is actually ssh/powershell connection so I want to isolate it.
It's there any handy way to do that??
I forgot mention it's laravel/php code.
You need to acquire a "lock" of some sort. If there is no lock, no one is accessing anything. If there is a lock, someone is accessing something and the rest should wait. The easiest way is to implement this using files and acquiring an exclusive lock. I'll post an example class (untested) and example usage. You can derive a working example using the sample code that follows:
class MyLockClass
{
protected $fh = null;
protected $file_path = '';
public function __construct($file_path)
{
$this->file_path = $file_path;
}
public function acquire()
{
$handler = $this->getFileHandler();
return flock($handler, LOCK_EX);
}
public function release($close = false)
{
$handler = $this->getFileHandler();
return flock($handler, LOCK_UN);
if($close)
{
fclose($handler);
$this->fh = null;
}
}
protected function acquireLock($handler)
{
return flock($handler, LOCK_EX);
}
protected function getFileHandler()
{
if(is_null($this->fh))
{
$this->fh = fopen($this->file_path, 'c');
if($this->fh === false)
{
throw new \Exception(sprintf("Unable to open the specified file: %s", $this->file_path));
}
}
return $this->fh;
}
}
Usage:
$lock = new MyLockClass('/my/file/path');
try
{
if($lock->acquire())
{
// Do stuff
$lock->release(true);
}
else
{
// Someone is working, either wait or disconnect the user
}
}
catch(\Exception $e)
{
echo "An error occurred!<br />";
echo $e->getMessage();
}

Should I check if array/collection value exists before trying to get it?

Should I check if a key exists and then get it or just get it (when I need to get it, not check if its set)?
What is more reliable? safer? faster?
Examples:
1) PHP redis (https://github.com/nicolasff/phpredis)
if ($redis->exists('key'))
echo $redis->get('key');
// VS
if ($value = $redis->get('key'))
echo $value;
2) PHP phalcon cookies(http://docs.phalconphp.com/pt/latest/reference/cookies.html)
if ($this->cookies->has('remember-me'))
echo $this->cookies->get('remember-me')->getValue()
// VS
if ($value = $this->cookies->get('remember-me')->getValue())
echo $value;
Thank you!
My interpretation of this problem is:
I don't like writing things like
if ($value = $redis->get('key'))
echo $value;
it makes code unclear.
Also, why is checking if variable exists so important? Because it simplifies control flow.
Let's consider that you're grabbing some data from service to render it on page. You can write low quality code with multiple ifs, but you can also try something like this:
offerServiceImpl.php
class offerServiceImpl implements offerService {
//... (some methods)
/**
* #param int $offerId
* #return Offer
* #throws InvalidArgumentException
* #throws RuntimeException
*/
public function getOffer($offerId)
{
if (!$offerId || !is_numeric($offerId)) {
throw new InvalidArgumentException("Invalid offer id: " . $offerId);
}
$offer = $this->offerDao->get($offerId);
if (!$offer) {
//could be your own exception class
throw new RuntimeException("Could not found offer " . $offerId);
} else {
return $offer;
}
}
}
offersControler.php
class offersController extends AbstractController{
public function index($id){
//... some code
try{
$offer = $this->offerService->getOffer($id);
} catch (InvalidArgumentException $ex) {
//log error, perform redirect to error 500
} catch (RuntimeException $ex){
//log another error, perform redirect to error 404
} catch (Exception $ex){
//log error, perform redirect to error 500
}
}
}

How to change exception message of Exception object?

So I catch an exception (instance of Exception class) and what I want to do is change its exception message.
I can get the exception message like this:
$e->getMessage();
But how to set an exception message? This won't work:
$e->setMessage('hello');
For almost every single case under the sun, you should throw a new Exception with the old Exception attached.
try {
dodgyCode();
}
catch(\Exception $oldException) {
throw new MyException('My extra information', 0, $oldException);
}
Every once in a while though, you do actually need to manipulate an Exception in place, because throwing another Exception isn't actually what you want to do.
A good example of this is in Behat FeatureContext when you want to append additional information in an #AfterStep method. After a step has failed, you may wish to take a screenshot, and then add a message to the output as to where that screenshot can be seen.
So in order to change the message of an Exception where you can just replace it, and you can't throw a new Exception, you can use reflection to brute force the parameters value:
$message = " - My appended message";
$reflectionObject = new \ReflectionObject($exception);
$reflectionObjectProp = $reflectionObject->getProperty('message');
$reflectionObjectProp->setAccessible(true);
$reflectionObjectProp->setValue($exception, $exception->getMessage() . $message);
Here's that example the Behat in context:
/**
* Save screen shot on failure
* #AfterStep
* #param AfterStepScope $scope
*/
public function saveScreenShot(AfterStepScope $scope) {
if (!$scope->getTestResult()->isPassed()) {
try {
$screenshot = $this->getSession()->getScreenshot();
if($screenshot) {
$filename = $this->makeFilenameSafe(
date('YmdHis')."_{$scope->getStep()->getText()}"
);
$filename = "{$filename}.png";
$this->saveReport(
$filename,
$screenshot
);
$result = $scope->getTestResult();
if($result instanceof ExceptionResult && $result->hasException()) {
$exception = $result->getException();
$message = "\nScreenshot saved to {$this->getReportLocation($filename)}";
$reflectionObject = new \ReflectionObject($exception);
$reflectionObjectProp = $reflectionObject->getProperty('message');
$reflectionObjectProp->setAccessible(true);
$reflectionObjectProp->setValue($exception, $exception->getMessage() . $message);
}
}
}
catch(UnsupportedDriverActionException $e) {
// Overly specific catch
// Do nothing
}
}
}
Again, you should never do this if you can avoid it.
Source: My old boss
Just do this, it works I tested it.
<?php
class Exception2 extends Exception{
public function setMessage($message){
$this->message = $message;
}
}
$error = new Exception2('blah');
$error->setMessage('changed');
throw $error;
You can't change Exception message.
You can however determine it's class name and code, and throw a new one, of the same class, with same code, but with different message.
You can extend Exception and use the parent::__construct to set your message. This gets around the fact that you cannot override getMessage().
class MyException extends Exception {
function __construct() {
parent::__construct("something failed or malfunctioned.");
}
}
here a generified snippet i'm using.
foreach ($loop as $key => $value)
{
// foo($value);
thow new Special_Exception('error found')
}
catch (Exception $e)
{
$exception_type = get_class($e);
throw new $exception_type("error in $key :: " . $e->getMessage());
}
An ugly hack if you don't know which kind of exception you're handling (that can have its own properties) is to use reflection.
try {
// business code
} catch (\Exception $exception) {
$reflectedObject = new \ReflectionClass(get_class($exception));
$property = $reflectedObject->getProperty('message');
$property->setAccessible(true);
$property->setValue($exception, "new message");
$property->setAccessible(false);
throw $exception;
}
You should use this crap wisely in very specific case when you don't have any other choice.
You can't change the message given by the Exception class. If you wanted a custom message, you would need to check the error code using $e->getCode() and create your own message.
If you really wanted to do this (in the only situation I can think that you might want to do it), you could re-throw the exception:
function throwException() {
throw new Exception( 'Original' );
}
function rethrowException() {
try {
throwException();
} catch( Exception $e ) {
throw new Exception( 'Rethrow - ' . $e->getMessage() );
}
}
try {
rethrowException();
} catch( Exception $e ) {
echo $e->getMessage();
}
The php Exception class has a __toString() method which is the only method within the Exception class that is not final, meaning it can be customised.
class HelloMessage extends Exception {
function __toString() {
return $this->getMessage()." you have an error with code: ".$this->getCode();
}
}
You use it as follows within try-catch block:
try {
if (2 > 0) {
throw new HelloMessage("Hello", 10);
}
} catch (HelloMessage $e) {
echo $e;
}
Output would be:
Hello you have an error with code: 10
You can extend Exception with your own, and put a setter in it
class MyException extends Exception
{
private $myMessage = '';
public function getMessage()
{
if ($this->myMessage === '') {
return parent::getMessage();
} else {
return $this->myMessage;
}
public function setMessage($msg)
{
$this->myMessage = $msg;
}
}
This is an improved version of David Chan's answer. It's a re-throw solution which uses get_class to rethrow the same exception type, and it passes all parameters to the constructor, even in the case of ErrorException, which has six rather than three constructor parameters.
foreach ($loopvar as $key => $value)
{
doSomethingThatMightThrow($value);
}
catch (\Exception $e)
{
$exception_type = get_class($e);
$new_message = "[key '" . $key . "'] " . $e->getMessage();
if ($e instanceof \ErrorException) {
throw new $exception_type($new_message, $e->getCode(), $e->getSeverity(), $e->getFile(), $e->getLine(), $e);
}
throw new $exception_type($new_message, $e->getCode(), $e);
}

phpunit doesn't throw exception

phpunit test:
public function testSizeOver64K() {
try {
$this->login();
$scriptname = 'test script4';
$this->fixture->installScript($scriptname, $this->scripts[$scriptname]);
}
catch (Exception $expected) {
return;
}
$this->fail('An expected exception has not been raised.');
}
Functions methods it calls
function installScript($scriptname, $script, $makeactive = false)
{
$this->cmdPutScript($scriptname, $script);
if ($makeactive)
$this->cmdSetActive($scriptname);
return true;
}
private function cmdPutScript($scriptname, $scriptdata)
{
if (self::STATE_TRANSACTION != $this->state) {
$msg = 'Not currently in TRANSACTION state';
$code = 1;
throw new Exception($msg, $code);
}
$stringLength = $this->getLineLength($scriptdata);
$this->doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata));
return true;
}
private function getLineLength($string) {
if (extension_loaded('mbstring') || #dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX)) {
$lenght = mb_strlen($string,'8bit');
if ( $lenght > 65536 ) {
$msg = "Script is over 64K";
throw new Exception($msg);
}
return $lenght;
} else {
$lenght = strlen($string);
if ( $lenght > 65536 ) {
$msg = "Script is over 64K";
throw new Exception($msg);
}
return $lenght;
}
}
Can someone give tips why phpunit doesnt catch the exception?
Use a debugger and step through the testcase to make sure your code actually throws the Exception in the first place. It's impossible to tell from your code whether the environment is setup in a way that would result in an Exception.
On a sidenote, you are supposed to throw less generic exceptions. You are using try/catch so the following is not applicable to your problem at hand, but take note of
Implemented GH-88: #expectedException (and setExpectedException()) no longer accept Exception as the expected exception class.
See changelog for PHPUnit 3.6 and https://github.com/sebastianbergmann/phpunit/pull/88
Chances are the problem is in your code and is not with phpunit at all.
See this test case:
<?php
function foo() {
throw new Exception("boom");
}
class MyFooTest extends PHPUnit_Framework_TestCase {
public function testArguments() {
try {
foo();
} catch (Exception $e) {
return;
}
$this->fail("nope");
}
}
it prints:
phpunit mep.php
PHPUnit 3.5.12 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 3.00Mb
OK (1 test, 0 assertions)
so boiled down to the essentials it works. It would be pretty strange if phpunit would change any of that behavior

Categories