LINUX.ORG.RU

[камень в огород] опять PHP


0

0

Сегодня, дети, я расскажу еще одну страшную сказку. Сказку об области видимости в PHP.

Вот вам безобидный пример кода с ошибкой:

<?php

class a{
    private $foo;
    public function setFoo($foo){
        $this->foo = $foo;
    }
}

class b extends a{
    public function getFoo(){
      return $this->foo;
    }
}

$c = new b();
$c->setFoo("Hello!");
echo $c->getFoo()."\n"; 

Даже распоследнее школие понимает, что здесь не так: getFoo() не может сработать, потому что foo надежно скрыто в недрах родительского класса. Тем не менее, PHP об этом даже NOTICE'ом не обмолвится! Впрочем, ошибку легко заметить и исправить ввиду того, что пример махонький. Когда кода побольше, сделать это порой не так легко — именно из-за того, что сам PHP об этом молчит как партизан.

Я напоролся на этот ляп, когда рефакторил немаленькую иерархию классов и вот как раз переделывал один класс с кучей if-ов в три класса с наследованием. И накололся именно о то, что все закрытые свойства и методы в начальном классе были приватными и, как водится, некоторые из них я забыл сделать protected. Потом долго удивлялся, что ж это все вдруг внезапно начало работать неправильно?

g++ о таких вещах хоть честно тебя обматерит, и на том спасибо.

★★★★★

Ответ на: комментарий от Chumka

Хм. Выругался.

Самое прикольное, правда, это то, что если ты свойство случайно переопределишь — ничего не будет. То есть вообще. Правда, setFoo() будет работать с одним foo, а getFoo() с другим; такое может быть, если у тебя в дереве классов есть внуки и ты случайно забываешь, в котором из классов должно было сидеть foo.

Отслеживать такие вещи довольно непросто, и никакого супер-strict'а в PHP для этого нет (сравнить хотя бы с перлом).

shimon ★★★★★
() автор топика

У меня белый экран, наверное я чайник

anonymous
()
Ответ на: комментарий от Chumka

А, не обращай внимания Шима - это тролль двухзвёздочный. Вечно постит тут всякие глупости. Кстати, по его словам, он уже лет пять пытается осилить похапэ.

anonymous
()
Ответ на: комментарий от shimon

На такое и в Java не выругается. Отсюда - простое правило: никогда не обращайся к данным чужого класса напрямую. Даже если это суперкласс текущего.

KRoN73 ★★★★★
()

Ты еще вопрос президенту задай об этом, главное тон таким же оставь. А нотайс оно выдаёт.

kost-bebix ★★
()
Ответ на: комментарий от KRoN73

> На такое и в Java не выругается.

Зато в C++ скажет, что такой-то member <Superclass::member> was hidden by <Subclass::member>. Сюрпрайз?

> Отсюда - простое правило: никогда не обращайся к данным чужого класса напрямую. Даже если это суперкласс текущего.


Когда текущий и суперкласс были отрефакторены из одного и того же класса, все углядеть трудно. А за остатками можно очень долго гоняться.

shimon ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> А, не обращай внимания Шима - это тролль двухзвёздочный. Вечно постит тут всякие глупости.

Чья бы корова мычала...

shimon ★★★★★
() автор топика
Ответ на: комментарий от shimon

> Зато в C++ скажет

Кто-то тебе запрещает писать на плюсах для веба?

ЗЫ: С НГ!

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.