Archive for June, 2008

php magic __set and __get

Sunday, June 15th, 2008

Last days I have a problem with php magic functions and specially with overloading. Here is an example code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Container
{
private $_data;
 
public function __set($key, $value)
{
$this->_data[$key] = $value;
}
 
public function __get($key)
{
return $this->_data[$key];
}
 
public function __isset($key)
{
return isset($this->_data[$key]);
}
 
public function __unset($key)
{
if ($this->__isset($this->_data[$key]))
unset($this->_data[$key]);
}
}

when you try to use this code with arrays for example:

1
2
3
4
$c = new Container;
$c->arr = array();
$c->arr['test'] = 'test';
var_dump($c->arr['test']);

it rise a notice: Indirect modification of overloaded property Container::$arr has no effect.
and $c1->arr[’test’] is null instead of test.

a work around is first to get this array into a temporary variable, make changes you need and then set it again.

1
2
3
4
5
6
$c = new Container;
$c->arr = array();
$tmpArr = $c->arr;
$tmpArr['test'] = 'test';
$c->arr = $tmpArr;
var_dump($c->arr['test']);

this one works as expected. Actually php interpreter seems to do same thing. Trying to get value if exists and change it. Problem is that when it takes this value there is no place to store it and rise this error. Trying to modify property in not existing array. Solution is to make this array available. Returning values by reference seems to work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Container
{
private $_data;
 
public function __set($key, $value)
{
$this->_data[$key] = $value;
}
 
public function &__get($key)
{
return $this->_data[$key];
}
 
public function __isset($key)
{
return isset($this->_data[$key]);
}
 
public function __unset($key)
{
if ($this->__isset($this->_data[$key]))
unset($this->_data[$key]);
}
}

Now this code works as expected:

1
2
3
4
$c = new Container;
$c->arr = array();
$c->arr['test'] = 'test';
var_dump($c->arr['test']);

Share/Save/Bookmark

SplFastArray

Tuesday, June 10th, 2008

Few days ago I’ve downloaded last version of php5.3 from snaps.php.net and I’ve made some tests with SplFastArray. Results are very strange for me:

here is result of last test I’ve made few minutes ago.

$ php fastarray.php
——————————————————————-
marker time index ex time perct
——————————————————————-
Start 1213124261.36967200 - 0.00%
——————————————————————-
simple array foreach 1213124261.57657300 0.20690083503723 13.10%
——————————————————————-
fast array foreach 1213124261.89191900 0.31534600257874 19.96%
——————————————————————-
simple array for 1213124262.36776400 0.47584509849548 30.12%
——————————————————————-
fast array for 1213124262.94954500 0.58178091049194 36.82%
——————————————————————-
Stop 1213124262.94959900 5.4121017456055E-5 0.00%
——————————————————————-
total - 1.5799269676208100.00%
——————————————————————-

and here is the source code I use for test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
$iterations = 1000000;
$a = new SplFastArray($iterations);
$b = array();
for ($i=0;$i<$iterations;$i++) {
$a[$i] = $i;
$b[$i] = $i;
}
require_once 'Benchmark/Timer.php';
$timer = new Benchmark_Timer();
$timer->start();
 
 
foreach($b as $k=>$v) {
}
$timer->setMarker('simple array foreach');
 
foreach($a as $k=>$v) {
}
$timer->setMarker('fast array foreach');
 
 
for ($i=0;$i<count($b);$i++) {
}
$timer->setMarker('simple array for');
 
 
for ($i=0;$i<$a->getSize();$i++) {
}
 
$timer->setMarker('fast array for');
 
$timer->stop();
echo $timer->display();
 
?>

Share/Save/Bookmark