0

think we have this script :

class String {
protected $text = null;
public function __construct($text){
    $this->text = $text;
}

public function __get($var){ return $this->$var; }

public function replace($search, $replace, $limit = -1, $ignoreCase = false){
    extract($GLOBALS, EXTR_REFS);
    return preg_replace($search, $replace, $this->text, $limit, $count);
}
}

class Setting {
private $active = "not active";

public function __get($var){
    return $this->$var;
}
}

$s = new Setting;

function replace(){
$string = new String('System is [var:$s->active]');
echo $string->replace('/\[var:([^\]]+)\]/ie', 'isset(\1)? \1: "";');
}

replace();

now $active property will not evaluate is it a bug or i should do something special ?

SOLVED
with a lot of thanks to dear Artefacto.
the problem was solved

i should implement __isset to use isset function for readonly property

Omid
  • 4,575
  • 9
  • 43
  • 74

3 Answers3

2

Your __get definition is wrong. You want instead:

public function __get($var){
    return $this->$var;
}

Now everything property can be read, but not necessarily written to. You just won't be able to read private variables defined in superclasses.

For instance:

<?php
class Setting {
    private $active = "not active";

    public function __get($var){
        return $this->$var;
    }
}
$s = new Setting;
echo preg_replace('/(\{%active%\})/e', '$s->active', 'System is {%active%}');

will print "System is not active".

Artefacto
  • 96,375
  • 17
  • 202
  • 225
0

Have to implement __isset function for String class when want to use isset()

class Setting {
    public function __isset($var){
        return isset($this->$var);
    }
}
Omid
  • 4,575
  • 9
  • 43
  • 74
0

You are mixing const with private, maybe?! There is no bug, if you want the variable active to behave like a readonly one, you should declare it as a constant. Like this:

class Setting {
    const ACTIVE = true;

    public function __get($var){
        return $var;
    }
}

Then access it like this Setting::ACTIVE.

Update

It won't evaluate because you are enclosing the variable inside single quotes. Try this:

preg_replace('/(\{%active%\})/e', "$Setting->active", 'System is {%active%}');

Missed the /e modifier, no need for double quotes or braces. :)

Shef
  • 44,808
  • 15
  • 79
  • 90
  • 1
    I understand what you're getting at, but readonly properties are not exactly the same as class constants. – BoltClock Jun 21 '11 at 14:21
  • @Shef: As `BoltClock` said readonly properties are something different. readonly property can be initial in run time – Omid Jun 21 '11 at 14:26
  • @BoltClock: It will behave like one, won't it? I know the `__set()` and `__get()`, but that will be horribly slower than this. However, I don't know what he is trying to accomplish exactly, i.e. which is the use case he is trying to apply a class readonly property to. – Shef Jun 21 '11 at 14:26
  • They are semantically different, so you can't just say `__set()` and `__get()` are slower. Class constants are defined at compile-time and are associated with classes; while read-only properties can be associated with objects and tend to be settable privately in the constructor (i.e. read-only applies to external sources). – BoltClock Jun 21 '11 at 14:29
  • @Omid Amraei: Where in your code are you initiating your variables? I was trying to give you a suggestion, if you were trying to accomplish another thing. Basically telling you to consider if this would solve your problem. However, I see that you wanted truly readonly properties, which has been already [answered here](http://stackoverflow.com/questions/402215/php-readonly-properties). – Shef Jun 21 '11 at 14:31
  • @BoltClock: Yes, you are right. If that's what he was after, then he should take a look at answered question mentioned in my comment above. – Shef Jun 21 '11 at 14:34
  • @Shef: Using `__get` or `__set` is not the main problem. as i mentioned the only problem is evaluation flag in preg_replace – Omid Jun 21 '11 at 14:36
  • @Omid Amraei: Updated my answer. If the double quotes won't solve the problem, try `"{$Setting->active}"`. :) – Shef Jun 21 '11 at 14:41
  • @Shef That's not necessary, preg_replace evaluates the 2nd argument dynamically, on each replacement. – Artefacto Jun 21 '11 at 14:44
  • @Artefacto: You are right. Then, everything works fine from what I tested here. The only thing which he might be missing, is if he didn't initialize the `$active` variable in the constructor. – Shef Jun 21 '11 at 14:53
  • @Shef: I edited codes. dear Artefacto helped to find out the real problem – Omid Jun 21 '11 at 15:08