Archive for the ‘ PHP ’ Category

Author : beriba | 02/09/2014

Have you ever wondered is there any way to get private or protected properties from other object? Of course you have. If you’re developing something from scratch this is totally unneeded. You can just made a property either public or make get/set methods. Of course the second option is way much better.
But sometimes you are using a third-party module, you just can’t edit it and you need a private/protected property. In PHP it’s not the end of the world. Below you can find two methods, which sets and gets (respectively) non-public values.

/**
 * Sets value of protected or private property in given object
 *
 * @param mixed  $object   Object in which we want to change property value
 * @param string $property Property name
 * @param mixed  $value    New property value
 */
protected function setNonPublicValue($object, $property, $value)
{
    $reflectionObject = new ReflectionObject($object);
    $reflectionProperty = $reflectionObject->getProperty($property);
    $reflectionProperty->setAccessible(true);
    $reflectionProperty->setValue($object, $value);
}

/**
 * Gets value of protected or private property from given object
 *
 * @param mixed  $object   Object in which we want to change property value
 * @param string $property Property name
 *
 * @return mixed
 */
protected function getNonPublicValue($object, $property)
{
    $reflectionObject = new ReflectionObject($object);
    $reflectionProperty = $reflectionObject->getProperty($property);
    $reflectionProperty->setAccessible(true);

    return $reflectionProperty->getValue($object);
}

This is very dirty solution and should be used only when you’re aware what you’re doing and only when no other ways are possible.

In the previous post I wrote about Windows Azure Queue. But back then, when I was playing with it I had a significant problem with creating it. The main difficulty was connecting to real Azure Queue (not emulated one). I couldn’t find anywhere how connection string should look like. After some ‚shotgun debugging’ I came up with something that works.

$queueRestProxy = ServicesBuilder::getInstance()->createQueueService('DefaultEndpointsProtocol=https;AccountName={your_account_name};AccountKey=4Gu6Jvm9c5zlaaGEmuA9GZqYr3RzqRfC0W20Yrjnu0sayRnhXeHMCQYWy0IfXnlwTWwPHW2fU+bJ8bqlJRBPgg==');

My AccountName in this string was lower case and you may want to write it that way if something doesn’t work with upper case letters.

I don’t know if it is still valid because it was 6 months ago or more but maybe it will be useful for someone.

Author : beriba | 11/07/2013

This post should have landed here long time ago. It haven’t because I didn’t have enough time to prepare it.

Some time ago I was testing Windows Azure combined with PHP. There were some tools and tutorials around the web. Tutorials were not really up to date. They were saying that development could be done both on windows or linux. And it’s almost true… almost. If you’ll combine it with continuous deployment from git repository, making your „hello world” is just a pleasure. But if you want to do something more, let’s say, add some database to your application, it’s getting tricky. You can develop it only on windows because sqlsrv drivers are out of date and they’re not working on linux. And there are more tricky moments.

One of them shows up when you want to get messages from the queue. Everything is normal when you want to peek 2, 10 or 20 messages. But when you want to peek more than 31 messages there is an unexpected fail. Below code is an example which triggers this error.

$message_options = new PeekMessagesOptions();
$message_options->setNumberOfMessages(32);

An error is saying what happened but that’s all.

400: Fail: Code: 400 Value: One of the query parameters specified in the 
request URI is outside the permissible range. details (if any): 
ďťżOutOfRangeQueryParameterValueOne of the query parameters specified in 
the request URI is outside the permissible range. 
RequestId:2e5ed254-51cf-42f4-9efe-3dc26e5ea902 
Time:2013-05-24T09:55:56.6088493Znumofmessages33132.

I’m a developer for a long time and I don’t expect any error to tell me every detail. And I’m aware that every technology has it’s limitations but let’s face it – possibility to peek just 31 messages? In cloud? Not good. Instead of saying the same thing twice, there could be some explanation in error message.
I still don’t know why this limit is so low but I don’t want to know. I hope this will be changed.

But there is one thing that I loved about Windows Azure. It’s the best admin panel (or whatever it is called) I’ve ever used. Everything is plain, simple and beautifully animated.

Author : beriba | 09/02/2012

In big projects, where many developers can put their fingers over the code sometimes unpredictable things can happen. It’s obvious. Especially when the project is written in PHP. Many classes, even more methods – big mess. In such projects it is not easy (if even possible) to know every name of every class. Sometimes PHP interpreter will tell you that:

Fatal error: Cannot redeclare class MyClass in /tmp/MyClass.php on line 4

It can be the result of this code:

class myClass {
}

class myClass {
}

And you can say: „Yeah, right. Who can write such stupid code”. I’ll say – you never know. But this is just a sample when you can expect such error. If you know how to trigger an error on purpose, you’re half way to avoid triggering it unexpectedly. Of course it gets harder when duplicated class names are in two different, not related files. The only solution for that is to rename one of the classes. If you don’t know how to find them, I’ll give you a solution in the end of this post.

Almost the same error could get a little bit tricky to resolve in some conditions. When you are using some kind of autoloader (for example Symfony Framework) and you declare classes of the same name in two different files it is very likely that you won’t get above error. Why? It’s because autoloader will load the first class and then replace it with second. When you’ll try to invoke a method on object (which you think is an instance of the first class) you’ll get an error:

Fatal error: Call to undefined method MyClass::doSomething() in 
/tmp/MyClass.php on line 6

But you have your class just in front of your face, the method exists and you think „what the…”. There could be more than one reason of this error. First is explained above. The second – code you’ve written is just in memory of your editor or IDE and was not saved in file. Yes, this could sometimes happen – espacially when you work on remote project. Just open the file in another editor and find out what’s inside. If it’s the first reason we need to check which class is actually loaded. For that you can use static method:

public static function getPathToObject($object, $method = '__construct')
{
    $object = new ReflectionObject($object);
    $method = $object->getMethod($method);
    $declaringClass = $method->getDeclaringClass();
    $filepath = $declaringClass->getFilename();
    return $filepath;
}

It uses reflection to find path to loaded object. If the given path is different from the file you’re looking at then you just need to rename one of the classes. If the paths are the same then… you can ask me in the comments and I’ll try to help 🙂

Author : beriba | 08/27/2012

Sometimes building query using Criteria can be very painful. And that’s a fact. There is also another thing – Propel is not as powerful as plain SQL. Sometimes you need to make very complex query to get some data from your database. If you’re in that point, consider using a view. Of course if your database supports them (PostgreSQL and MySQL does).

When view is not what you are looking for or you want to strictly write SQL query and execute it via Propel, here’s how to do this:

$sql = "SELECT * FROM table;"; //your SQL query
$conn = Propel::getConnection();
$st = $conn->prepare($sql);
$st->execute();
$results = $st->fetchAll(PDO::FETCH_ASSOC);
//$results - associative array of results
//each element is as row
//every element is an array where keys are names of columns 
//and values are just values of these columns
Author : beriba | 08/17/2012

Sometimes when you’re building Criteria object you want to know what exactly Propel will produce. To be sure about the query or to debug it. You can do it as simple as that:

$params = array();
$sql = BasePeer::createSelectSql($criteria, $params);
var_dump($sql); //SQL query
var_dump($params); //array of params passed to SQL