Asked  7 Months ago    Answers:  5   Viewed   36 times

In using PHP's DOM classes (DOMNode, DOMEElement, etc) I have noticed that they possess truly readonly properties. For example, I can read the $nodeName property of a DOMNode, but I cannot write to it (if I do PHP throws a fatal error).

How can I create readonly properties of my own in PHP?

 Answers

80

You can do it like this:

class Example {
    private $__readOnly = 'hello world';
    function __get($name) {
        if($name === 'readOnly')
            return $this->__readOnly;
        user_error("Invalid property: " . __CLASS__ . "->$name");
    }
    function __set($name, $value) {
        user_error("Can't set property: " . __CLASS__ . "->$name");
    }
}

Only use this when you really need it - it is slower than normal property access. For PHP, it's best to adopt a policy of only using setter methods to change a property from the outside.

Wednesday, March 31, 2021
 
PeterTheLobster
answered 7 Months ago
95

This is very similar to a question a user asked me recently the forum for my book SQL Antipatterns. I gave him an answer similar to this:

$sql = "SELECT name, address, city FROM tableA JOIN tableB ON tableA.id = tableB.id";

$params = array();
$where = array();

if (isset($price) ) {
    $where[] = '(price = :price)';
    $params[':price'] = $price;
}
if (isset($sqft) ) {
    $where[] = '(sqft >= :sqft)';
    $params[':sqft'] = $sqft;
}
if (isset($bedrooms) ) {
    $where[] = '(bedrooms >= :bedrooms)';
    $params[':bedrooms'] = $bedrooms;
}

if ($where) {
  $sql .= ' WHERE ' . implode(' AND ', $where);
}

$stmt = $dbh->prepare($sql);

$stmt->execute($params);
$result_set = $stmt->fetchAll(PDO::FETCH_ASSOC);
Wednesday, March 31, 2021
 
oroshnivskyy
answered 7 Months ago
68

You can implement your own way to iterate over object just by implementing Iterator interface. By implementing methods next and current you define how to get current element and how to get the next one (but you will have to implement all methods).

For iteration use

foreach ($o as $k => $v) {
  print $k . '->' . $v . PHP_EOL;
}

Care to see some example? Did you understand it from link above?

On the other hand if you want to use your object as array, check ArrayObject interface or for simplier use ArrayAccess interface

Wednesday, March 31, 2021
 
Corne
answered 7 Months ago
60

This is happening because the concatenation operator has a higher precedence than the addition or subtraction operators, but multiplication and division have a higher precedence then concatenation.

So, what you're really executing is this:

echo ("$a + $b  = " . $a) + $b;
echo ("$a - $b  = " . $a) - $b;

In the first case, that gets turned into this:

"1 + 2 = 1" + $b

Which PHP tries to convert "1 + 2 = 1" into a number (because of type juggling) and gets 1, turning the expression into:

1 + 2

Which is why you get 3. The same logic can be applied to the subtraction condition.

Instead, if you put parenthesis around the calculations, you'll get the desired output.

echo "$a + $b  = " . ($a + $b);
echo "$a - $b  = " . ($a - $b);
Saturday, May 29, 2021
 
JohnnyW
answered 5 Months ago
41

You need to tell the compiler that you also want a setter. A common way is to put it in a class extension in the .m file:

@interface YourClass ()

@property (nonatomic, copy) NSString* eventDomain;

@end
Sunday, August 8, 2021
 
mattltm
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :