This seems kind of limitation to me, indeed, if you use __toString() magic method for anything other than simple object variables concatenation, your code should be able to throw exceptions. Consider you have an object that generates XML as output, and you decide to provide even nicer interface, so that anyone using it in string context to get access to that XML. XML generation might not go well, and the obvious way to let the client know about this is to throw an exception. However, this is not possible (most probably due to some internal architecture limitations – as I honestly see no reason why this ideologically wrong).
One (not quite pretty) way to still provide some feedback from __toString() is using trigger_error:
public function __toString()
{
try {
$output = $this->generateXml();
return $output;
} catch(Exception $e) {
trigger_error($e->getMessage(), E_USER_ERROR);
return '';
}
}
If you know of a better option, let me know!
Magic Methods, PHP5
Starting with PHP5 almost any PHP installation contained SPL (Standard PHP Library) extension – with few exceptions, when hosters intentionally disabled it. With PHP 5.3 out, this extension is considered to be within PHP core, and as such it’s not possible to disable it anymore. This in fact is a good thing, as SPL really deserves to be the core component.
In an attempt to shed some light on and to draw attention to SPL, I plan to post several articles discussing various parts of this extension. I will start with SPL Interfaces so that you can grasp immediately the usefulness of the SPL.
Comprehending SPL interfaces presupposes that you know standard interfaces that come build-in with PHP5. So, I wrote preliminary article discussing them – I consider it to be a prerequisite for good understanding of the current material.
Covered in this article:
Read the rest of this entry
Interfaces, PHP5, SPL
Note: This article serves as preliminary for SPL Interfaces article to be published later on.
I wanted to provide good overview of (highly under-used) Standard PHP Library (SPL) starting with interfaces. However, without firstly discussing predefined interfaces, which come bundled with each and every PHP distribution, discussion of SPL-provided ones seemed to be incomplete.
To be covered in this article:
Read the rest of this entry
OO, PHP5, SPL
Sometimes, especially when dealing with variations of factory pattern, single method (namely factory()) can return objects of different types, so NetBeans is unable to guess the exact type of returned instance and as such cannot auto-complete. Indeed, you can setup return type using phpDoc syntax:
/**
* @return Some_Base_Abstract_Class_Name
*/
public function factory($adapter)
but that doesn’t work if returned objects are specifications of more general abstract class (exactly the case with factory).
As it turned out, you can easily resolve this issue – just document your variable with @var, before calling factory() method:
/**
* @var Some_Specific_Class $foo
*/
$foo = Magic::factory('adapterName');
$foo-> // and NetBeans opens pop-up list with available attributes and methods
The good news, you can use this method in any scope – it just works
I love NetBeans!!
UPD: Well, actually NetBeans seems to be picky of scope – as reported by others (and confirmed by myself).
UPD1: Actually NetBeans handles this quite well, just use vdoc (review this and this for details)
NetBeans, PHP5
Zend Framework (ZF) is the MVC framework. Of course you can use its components in a non-MVC way (and I actually do so in my WP UMapper plugin), but in that case, I suppose, you do not have to worry about models auto-loading.
Frameworks make our coding life easier, and ZF is not an exception – you need very little code to get your application skeleton working. And when it comes to MVC, ZF handles almost everything – your action controllers are triggered, your views are loaded, w/o you having to worry about them. Not the same with models. If you comply to directory layout advised by ZF, you have “models” folder, but framework doesn’t interact with it in any way.
Models are simply classes, containing application logic, and to initialize one of them you have to make sure that:
a) containing directory is withing include_path
b) you require_once the class file before using it
I wanted my models to be available without any additional hassle, so I decided to find a way to auto-load models from within my controller actions.
Read the rest of this entry
design, PHP5, Zend Framework
Иногда возникает ситуация, когда нужно проверить существует ли заданный ключ в массиве или нет. Предположим, что если ключа нет, нужно выдать сообщение об ошибке. Если такой ключ один, то
1
2
3
4
| $myArr = array();
if (!isset($myArr['needle'])) {
printf('Ключ "%s" не найден!!', 'needle');
} |
легко решит эту задачу. Однако когда ключей несколько стоит использовать array_diff:
1
2
3
4
5
6
| $requiredParams = array('needle', 'anotherOne'); // список ключей
$myArr = array('someKey');
if ($params = array_diff($requiredParams, array_keys($myArr))) {
printf('Следующие ключи не найденны: %s!!', implode(', ', $params));
} |
В случае если все обязательные ключи найденны, результат выполнения функции будет равен пустому массиву (при преобразовании в булев, которое происходит автоматом внутри if(), пустой массив интерпритируется как false), соответственно блок не будет выполнен. Если же массив непустой, то блок if() будет выполнен.
Данный метод очень удобен, если вы имеете функцию/метод, который получает одним из аргументов массив, в котором должны содержаться какие-либо обязательные ключи, для корректного исполнения дальшейшего кода.
Удачных выходных!
PHP5
Хотя это очевидно и подчеркивается в PHP мануале, тем не менее поймал себя на мысли, что неверно интерпретировал следующий код:
1
2
3
4
5
| $a = 12;
$b = &$a;
unset($b); // удаляем ссылку
var_dump($b);
var_dump($a); |
Результат исполнения:
Таким образом, при удалении ссылки, удаляется именно ссылка, оригинальная переменная остается нетронутой, и указывает на все то же значение. В общем, в PHP, ссылки (reference) являются не чем иным, как алиасами (alias) – думать о них как об указателях (pointers) неправильно.
UPDATE: When you unset the reference, you just break the binding between variable name and variable content. This does not mean that variable content will be destroyed. Т.е. когда ссылка удаляется, на деле уничтожается лишь связь между именем переменной и ее значением. Это значит, что при уничтожении переменной путем unset(), значение не уничтожается.
PHP5
Готовлюсь к PHP5 сертификации и вот, просматривая доки, наткнулся на нетривиальный пример.
Как вы все наверняка знаете перменные в PHP могут содержать буквы (a-zA-Z), цифры (0-9) и символ подчеркивания (“_”). Дополнительное требование: имя переменной должно начинаться либо с буквы, либо с символа подчеркивания. Так вот используя variables variable (кстати, кто знает как правильно произносится это слово? произносится как “вэриэбл”, а не “вэрайбл” как казалось бы – спасибо профу по статистике, лет 8 назад научил) можно создавать переменные с названиями состоящими из чисел:
1
2
3
| $name = 123; // название переменной 123 в обычном случае нелегально
$$name = 456; // однако используя переадресацию работает!
echo ${123}; // выдаст 456 |
Естественно, такое применение не приветствуется, однако работает!
PHP5, Zend Certification