Поиск Картинки Карты Play YouTube Новости Почта Диск Ещё »
Войти
Ваш браузер не поддерживает сервис Вопросы и ответы, поэтому некоторые функции могут работать некорректно. Просмотреть список поддерживаемых браузеров можно здесь.
Вопросы и ответы
Возможно ли в PHP определить класс внутри другого класса?
Возможно ли в PHP определить класс внутри другого класса?
Такой код:

<?

 class A
 {
   class B
   {
   }
 }

?>

порождает ошибку: "PHP Parse error:  syntax error, unexpected T_CLASS, expecting T_FUNCTION in C:\temp\test.php on line 5"

Является ли невозможным в PHP определить класс внутри другого класса, или есть специальный синтаксис для этого?

(Кстати, почему "expecting" именно T_FUNCTION, а не T_VAR или T_PUBLIC, например?)

P.S.: Класс внутри функции определяется без проблем:

<?

 function f()
 {
   class C
   {
   }
 }

?>
Примечание №1 22 июня 2009 г., 0:37:00
Domovoy, да, забыл сказать, конечно PHP5.

C:\>php --version
PHP 5.2.6 (cli) (built: May  2 2008 18:02:07)
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies

Спасибо за ссылку, но, как ни странно, пример не работает, выдаёт загадочную ошибку: "PHP Parse error:  syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting '{' in C:\temp\test2.php on line 2".

Ну да ладно, буду знать, в каком направлении копать.

А вообще-то меня как раз интересовало такое определение, чтобы внутреннего класса вообще не видно было извне внешнего класса. "Private Class", так сказать. :-)
Примечание №2 24 июня 2009 г., 19:21:13
Azrael_ru, красиво говорите... но не то.
Такой код вызывает ту же ошибку:

<?

 class A
 {
 }

 class A::B
 {
 }

?>

PHP Parse error:  syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM, expecting '{' in C:\temp\test2.php on line 7

Поясню, откуда взялась такая задача. Есть класс, которому для чисто внутренних целей нужен другой класс, нигде в других местах не нужный. Логично было бы описать его внутри основного класса, чтобы не засорять пространство имён и т.п. Ну да ладно, подождём нэймспэйсов, авось они решат этот вопрос...
Примечание №3 05 нояб. 2010 г., 9:19:20
Evgeniy Savichev, я, конечно, понимаю, что у нас в национальных традициях на любой вопрос, как сделать что-то, — отвечать: «А оно тебе надо?» Прошло больше года, и я понятия не имею, чего я конкретно хотел. (К тому же, за прошедшее время я имел счастье «уйти» на Python, и теперь половые трудности PHP меня мало волнуют.) Однако, взглянув на вопрос и на Ваши «размышления на тему», хочется спросить Вас: «Вы вообще об чём?»

«Я так понимаю, внутренний класс понадобился как формализованная структура, которых инстанциируется N штук и чё-то там в цикле... Так поля структуры можно формализовать и константой, и не обязательно для этого класс, обычного хеша хватит.»©

При чём здесь хеш, константы, цикл (и жуткое слово «инстанциируется»)? С тем же успехом можно сказать, что ООП вообще не нужен, т.к. всё можно написать и на «plain C». А в PHP есть такая замечательная штука, как “array”, в которую можно засунуть что угодно и жить счастливо. Так, может, ну их на фиг, эти классы?

P.S. Класс внутри класса нужен ровно по тем же причинам, по которым он нужен в любом другом месте программы. (Надеюсь, так понятнее.)
Ответы (6)
Сортировать по: голосам | времени
Войдите или зарегистрируйтесь, чтобы ответить на этот вопрос.
Веб-поиск Google
Поиск в Картинках Google
Видео YouTube
Поиск
Введите URL
Для поиска в Интернете введите запрос в это окно.
Для поиска в Интернете введите запрос в это окно.
Для поиска в Интернете введите запрос в это окно.
Введите запрос
Вставьте URL в поле ниже:
Не удалось загрузить веб-сайт
Поиск на YouTube
Добавить ссылку на видео
Как-то так:
<?php
class DB::MySQL {
var $host = '';

   function db_connect($user) {
       print "Connecting to MySQL database '$this->host' as $usern";
   }
}

class DB::Oracle {
   var $host = 'localhost';

   function db_connect($user) {
       print "Connecting to Oracle database '$this->host' as $usern";
   }
}

$MySQL_obj = new DB::MySQL();
$MySQL_obj->db_connect('Susan');

$Oracle_obj = new DB::Oracle();
$Oracle_obj->db_connect('Barbara');
?>

PHP 5 используешь?
Ссылки
22.06.09
Domovoy
<?php
class DB::MySQL

Не может быть такого имени у класса, поэтому и Parse Error
Имя класса alphabetical.

> почему "expecting" именно T_FUNCTION, а не T_VAR или T_PUBLIC, например
потому что, T_VAR или T_PUBLIC, т.е. задание свойств класса является опциональным.
Парсер смотрит их, потом T_FUNCTION, функции нет - parse error

Что-то похожее можно сделать так
<?php
class A
{
 public function __construct()
 {
   include 'classB.php'; // где идет декларация класса
 }
}

Только это не поможет, создать экземпляр класса B можно будет в любой точке кода когда класс уже загружен
$obj = new B();

Если нужно спрятать объект, то нужно сделать так
class A
{
 private $_classB;

 public function __construct()
 {
   $this->_classB = new B();
 }
}

Однажды загруженный класс остается в памяти до завершения скрипта.
24.06.09
Azrael_ru
Дополнительная информация: T_PAAMAYIM_NEKUDOTAYIM означает двойное двоеточие на иврите.
18.01.10
crimaniak
А почему не решить это private методами/свойствами самого же класса? На то они и private вообще-то ;).
Я так понимаю, внутренний класс понадобился как формализованная структура, которых инстанциируется N штук и чё-то там в цикле... Так поля структуры можно формализовать и константой, и не обязательно для этого класс, обычного хеша хватит. Скажите цель создания внутреннего класса - будет ответ полезнее.
При таком дополнении исправлюсь. Не встречал ни одного случая, где это реально нужно. Но если вопрос теоретический, тогда ответ такой: в PHP (независимо от версии пока) нет нельзя. Возможно, что-то из abstract, interface или паттерны factory либо proxy решают ту же задачу?

PS: однако, любопытно, какое практическое применение такой структуры, если несложно? интересно же.
class Example1 extends ExcClass { }
class Example2 implements RefClass { }
class Example3 extends ExcClass implements RefClass { }
22.06.09
DimoNya
Об этом вопросе
Баллов за лучший ответ: 30
Просмотров: 5474
Ответов: 6
Похожие вопросы
ответов: 4 Голосов: 0
ответов: 5 Голосов: -2
ответов: 1 Голосов: 1
ответов: 2 Голосов: 0
ответов: 2 Голосов: 0
ответов: 10 Голосов: 0
ответов: 1 Голосов: 0
ответов: 11 Голосов: 0
x
©2013 Google - Условия использования - Правила в отношении веб-контента - Политика конфиденциальности - Принципы сообщества