Переопределение protected свойства из публичной части самим интепретатором. Почему?

Develar

Новичок
Переопределение protected свойства из публичной части самим интепретатором. Почему?

Я привык читать руководства и не писать на форумах, решая сам свои проблемы, но тут я не могу удержаться и спрашиваю скорее из любопытства, а не желания решить проблему.

Согласно теории, если в мы классе определяем static protected $variable никто не сможет изменить данную переменную вне класса - только посредством методов доступа.

определение свойства
PHP:
static protected $type = array();
определение метода доступа
PHP:
/**  	 
* Возвращает одну или все вершины пути, выраженного в типе  	
 * @param int $level_number = NULL Номер уровня вершины  	 
* @return mixed  	 
*/  	
static function getType($level_number = NULL)  	
{  		
if (isset($level_number))  		
{  			
return self::$type[$level_number];  		
}  		
else  		
{  			
return self::$type;  		
}  	
}
в коде вне класса
PHP:
$object_type = array_pop((ObjectPath::getType()));
если мы вызов ObjectPath::getType() не обрамляем крыглыми скобками - интерпретатор выдаст ошибку - все правильно, ведь array_pop принимает только по ссылке, а не по значению. А вот если обрамляем - вот это самое загодочное и смешное - защищенное свойство класса переопределяется вне класса - из массива ObjectPath::type удаляется последний элемент.

Скажите, это недокументированная возможность или баг? Или я чего-то не понимаю?

PHP Version 5.1.0
Build Date Nov 23 2005 23:54:40
System Windows NT 5.1 build 2600
Server API CGI/FastCGI

P.S. Вопрос "зачем это нужно" задавать не надо - поведение выше есть факт и мне хочется понять его причины.
 

tony2001

TeaM PHPClub
можно повторить всё то же, но по-русски?
лучше всего - без слов, а просто примером кода, который можно скопировать и выполнить.
 

svetasmirnova

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

itprog

Cruftsman
Скорее всего он про:
PHP:
class ObjectPath {
static protected $type = array('test','to');
static function getType()      {              
return self::$type;             
}
function printType() {
var_dump(self::$type);
}
}
ObjectPath::printType();
$object_type = array_pop((ObjectPath::getType()));
ObjectPath::printType();
Результат: array(2) { [0]=> string(4) "test" [1]=> string(2) "to" } array(1) { [0]=> string(4) "test" }
 

Develar

Новичок
class ObjectPath
{
static protected $type = array();

static function getType($level_number = NULL)
{
if (isset($level_number))
{
return self::$type[$level_number];
}
else
{
return self::$type;
}
}

static function construct()
{
self::$type = array(0 => 'Main');
}

static function beforeArrayPop()
{
var_dump(self::$type);
}

static function afterArrayPop()
{
var_dump(self::$type);
}
}

ObjectPath::construct();

ObjectPath::beforeArrayPop();

$object_type = array_pop((ObjectPath::getType()));

ObjectPath::afterArrayPop();
 

itprog

Cruftsman
Develar
Перечитай про ссылки...
И самое главное: http://php.rinet.ru/manual/ru/language.references.whatdo.php
Замечание: $a и $b здесь абсолютно эквивалентны, но это не означает, что $a указывает на $b или наоборот. Это означает, что $a и $b указывают на одно место.
-~{}~ 25.11.05 16:04:

_RVK_
а я не говорил что работает не так.
 

tony2001

TeaM PHPClub
если можно - в три раза меньше код, без функций "before", "after", "during_the_process" etc.
+ ожидаемый результат
+ действительный результат
 

Develar

Новичок
itprog, Вы меня опередили.

Суть: никто вне класса не имеет права переопределять защищенные свойства напрямую. Только через методы доступа.

-~{}~ 25.11.05 16:06:

tony2001 - запусти код представленный мной. никто вне класса не имеет права переопределять защищенные свойства напрямую. Только через методы доступа.

-~{}~ 25.11.05 16:07:

Я ожидаю что мне вернут последнее значение из массива type и при этом оно останется неизменным - то есть из самого массива элемент не удалится - ведь он protected.
 

_RVK_

Новичок
Develar
Так ты метод и используешь... в чем вопрос?

-~{}~ 25.11.05 16:09:

Функция array_pop удаляет последний элемент. Почему она не долэжна этого делать?
 

Develar

Новичок
Автор оригинала: _RVK_
Develar
Так ты метод и используешь... в чем вопрос?

-~{}~ 25.11.05 16:09:

Функция array_pop удаляет последний элемент. Почему она не долэжна этого делать?
Потому что это protected свойство. Если Тони скажет что это нормальное поведение PHP, тема закрыта.
 

itprog

Cruftsman
А я даже не заметил,
PHP:
class ObjectPath {
static protected $type = array('test','to');
static function getType()      {              
return self::$type;             
}
function printType() {
var_dump(self::$type);
}
}
ObjectPath::printType();
$types = array_pop(ObjectPath::getType());
ObjectPath::printType();
Результат array(2) { [0]=> string(4) "test" [1]=> string(2) "to" } array(2) { [0]=> string(4) "test" [1]=> string(2) "to" }

если заменить на $types = array_pop((ObjectPath::getType())); то:
array(2) { [0]=> string(4) "test" [1]=> string(2) "to" } array(1) { [0]=> string(4) "test" }
 

Develar

Новичок
itprog Твой код не выполнится
$types = array_pop(ObjectPath::getType()); при error_reportig = 4096 это ошибка
 

svetasmirnova

маленький монстрик
Develar
ну а что мешает сделать так:
PHP:
 $types = array_pop($temp = ObjectPath::getType());
 

Screjet

Новичок
tony2001
PHP:
function test( &$var ){
    $var[] = "!";
}

class A {
    static protected $a = array('Hello','World');
    function get_a(){
        return self::$a;
    }
    function print_r(){
        print_r(self::$a);
    }
}

#echo array_shift( (A::get_a()) );
test( (A::get_a()) );
A::print_r();
В 5.0.5 такое же поведение.
Похоже привидение к булевому типу возвращает переменную по ссылке.
 

Develar

Новичок
Strict Standards: Non-static method A::get_a() should not be called statically in e:\home\airs\www\example.php5 on line 18

Strict Standards: Non-static method A::print_r() should not be called statically in e:\home\airs\www\example.php5 on line 19
Array ( [0] => Hello [1] => World [2] => ! )
 
Сверху