О области и ООП в PHP

У меня возникли проблемы с пониманием того, как работать с объектами.

Конкретный код:

class first{ class second{ public function widgets(){ $a_variable = $a_value; } #1 } $second = new second; #2 } #3 $first = new first; 
  1. Если я инициализирую $a_variable как $a_variable он доступен только внутри функции, правильно?
  2. Если я инициализирую $a_varialbe как $this->a_variable он доступен только внутри класса второй, правильно?
  3. Можно ли инициализировать $a_variable как $first->second->a_variable ? Если да, то как я могу назвать это на #1 , #2 и #3 ?
  4. Можно ли инициализировать $a_varialbe as $this->second->a_variable ? Если да, то как я могу назвать это на #1 , #2 и #3 ?

Как вы можете видеть, я просто путаюсь, как работает ООП.


Прежде всего, я хочу выразить, насколько я ценю всю помощь. Я уже научился более чем достаточно, чтобы рассмотреть этот вопрос – удачный успех.

Тем не менее, даже если он плохо сформулирован, psuedo-code и недействительный синтаксис, этот код запускается.

 class class_1{ public function function_1(){ require('class_2.php'); public function function_2_callback(){ //%%%%%% How do I set a variable here and get the DATA... } $this->class_2 = new class_2("function_2_callback"); } } $class_1 = new class_1; //&&&&&&&&&& Get the DATA here? /* CONTENTS OF class_2.php */ class class_2($callback){ call_user_function($callback); } 

Даже если мы должны рассматривать это как упражнение. Может ли кто-нибудь сказать мне, как я должен сначала установить (@ %%%%%%%), а затем вызвать переменную (@ &&&&&&&&), как показано?

Related of "О области и ООП в PHP"

Во-первых: то, что у вас там, не работает, вы не можете объявить класс внутри класса так, как вы это делаете (несмотря на условное объявление класса внутри функции, чего вы не должны делать).

Область применения PHP (включая OOP) очень проста:

  1. переменные имеют функцию
  2. свойства объекта доступны, если у вас есть ссылка на объект
  3. видимость свойств объекта может быть ограничена

Единственный реальный объем, который у вас есть, – это область возможностей для переменных:

 $a = 'foo'; function bar() { $a = 'bar'; } 

Два $a s полностью не связаны между собой в разных областях. Так просто.

 class Foo { public $a = 'foo'; public function bar() { $this->a; // foo $a = 'bar'; } } $foo = new Foo; $foo->a; // foo 

Свойство объекта не имеет области видимости. Вы можете получить к нему доступ, если у вас есть объект в области видимости . Выше, $foo – объект. Он находится в области видимости, его свойство a является public , поэтому к нему можно получить доступ с помощью $foo->a . Внутри класса свойство доступно через $this->a .

$a = 'bar' A $a = 'bar' является локальной переменной в функции и не имеет ничего общего с $this->a . Он недоступен нигде, кроме функции. См. Правило №1, область действия.

 class Bar { protected $b = 'bar'; public function baz() { $this->b; // bar } } $bar = new Bar; $bar->b; // doesn't work 

Если видимость не является public , свойство (здесь b ) недоступно извне самого класса. Внутри класса вы можете получить доступ к нему, используя $this->b , но не извне, используя $bar->b . Речь идет не о сфере видимости , а о видимости.

И это в значительной степени правила области в PHP.

Прежде всего, ваш пример неверный код. PHP не поддерживает вложенные классы, что означает класс внутри класса.

если вы определяете класс, переменная, инициализированная внутри метода, является локальной для этого метода, тогда как вы можете «инициализировать» атрибут с помощью $ this-> newattribute, вы должны были объявить его и его видимость раньше (прежде чем писать метод public / private / protected $ varname = "начальное значение";).

Ваши вопросы 3 и 4 имеют смысл в другом контексте, это когда объект передается как член другого объекта, см. Пример ниже.

Если вы построите это как

 <?php class First { public $second; } class Second { public $a_variable; } $foo = new First(); $foo->second = new Second(); 

вы можете получить к нему доступ:

 $foo->second->a_variable = "foo"; 

или внутри метода во втором

 $this->a_variable; 

или в рамках метода, вначале с

 $this->second->a_variable; 

Вы не должны вставлять такие классы. Это даже не должно быть. Сначала я предлагаю запустить код. Есть несколько инструментов онлайн для тестирования небольших фрагментов кода PHP, таких как это .

Для запуска кода, как вы могли ожидать, он должен выглядеть так:

 class second{ public function widgets(){ $a_variable = $a_value; } } class first{ public $second; public function __construct() { $this->second = new second; } } $first = new first; 

Переменная, начинающаяся с $ [az] +, является локальной для функции. Свойство, начинающееся с $ this -> [az] + (где [az] равно 1 или более буквам), является частью объекта.

Есть некоторая документация на php.net, которая описывает специфику объектов в php здесь .

Если я инициализирую $ a_variable как $ a_variable, он доступен только внутри функции, правильно?

Да исправить. Он начинается с $ [az]. Не совсем верно, если вы используете ключевое слово global , но это обескуражено.

Если я инициализирую $ a_varialbe как $ this-> a_variable, он доступен только внутри класса второй, правильно?

Да, но сначала вы должны объявить об этом. Вы можете сделать это с помощью public $variable protected $variable или private $variable . public означает, что свойство может быть доступно извне, тогда как private означает, что только сам класс может получить к нему доступ. protected является закрытым для внешнего, но общедоступным для классов, которые распространяются от вашего класса.

( public / private / public стал доступен в PHP 5. В PHP 4 вы использовали бы var $variable , которая по умолчанию будет публичной в PHP 5)

Можно ли инициализировать $ a_variable как $ first-> second-> a_variable?

Вы можете произвольно инициализировать переменные класса, не объявляя их, но это не то, что вы должны делать.

Если да, то как я могу назвать это на # 1, # 2 и # 3?

Вы не можете вызвать код там (в вашем примере). Код должен находиться внутри функции или в глобальном контексте (вне определения класса).

Краткое объяснение классов

 class foo{ // This can be accessed anywhere public $i_am_public; // This can be accessed within this class and any sub classes protected $i_am_protected; // Thi can only be accessed within this class private $i_am_private; // This function can be accessed anywhere public function foo_function(){ // This variable is only available in this function // it cannot be accessed anywhere else $variable = 'Hello World'; // However, you can access any of the other variables listed above // like so $this->i_am_public = 'public'; $this->i_am_protected = 'protected'; $this->i_am_private = 'private'; // Write these variables echo $this->i_am_public; echo $this->i_am_protected; echo $this->i_am_private; } } $foo = new foo; $foo->foo_function(); // You can change any publicly defined variables outside // of the class instance like so $foo->i_am_public = 'testing'; 

Конкретные ответы на вопросы

Прежде чем я пойду дальше, я настоятельно рекомендую вам не определять класс внутри класса! Вместо этого используйте расширения класса, которые я объясню позже. На самом деле, я удивлен, что ваш код даже работает!

Если я инициализирую $ a_variable как $ a_variable, он доступен только внутри функции, правильно?

Да, это будет доступно только внутри функции. Если вы хотите получить к нему доступ за пределами функции, вам необходимо определить ее вне функции, используя одно из определений области видимости public, protected, private .

Если я инициализирую $ a_varialbe как $ this-> a_variable, он доступен только внутри класса второй, правильно?

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

Можно ли инициализировать $ a_variable как $ first-> second-> a_variable? Если да, то как я могу назвать это на # 1, # 2 и # 3?

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

Можно ли инициализировать $ a_varialbe как $ this-> second-> a_variable? Если да, то как я могу назвать это на # 1, # 2 и # 3?

Пожалуйста, см. Выше ответ 🙂

Гнездовые классы

Как уже упоминалось, я никогда не видел этого раньше, и я удивлен, что он даже работает. Вы должны обязательно изменить эту структуру.

Одним из предложений было бы использовать такие расширения:

 class foo{ // This can be accessed anywhere public $i_am_public; // This can be accessed within this class and any sub classes protected $i_am_protected; // Thi can only be accessed within this class private $i_am_private; public function foo_function(){ echo 'Hello World'; } } class bar extends foo { // This is a public function public function baz(){ // These will work $this->i_am_public = 'public'; $this->i_am_protected = 'protected'; // This will not work as it is only available to // the parent class $this->i_am_private = 'private'; } } // This will create a new instance of bar which is an // extension of foo. All public variables and functions // in both classes will work $bar = new bar; // This will work because it is public and it is inherited // from the parent class $bar->foo_function(); // This will work because it is public $bar->baz();