Всем привет. Как обычно занимался своими делами и наткнулся на необходимость создать некую структуру со строго определенными полями. Окей, думаю я, что бы не плодить бестолковый класс в отдельном файле, определю анонимный класс и будет мне счастье. И тут вспомнил Pascal/C/C++/C#/etc. Структуры! Где же вы? Как же было бы круто щас создать именованную структуру, и получить/вернуть ее можно с тайпхинтом. Погуглил RFC - нету! Так вот, если есть тут единомышленники, присоединяйтесь, будем делать RFC, один я не справлюсь.
В Си структура определяется так PHP: struct Structure { public int field = 0; // поле структуры // конструктор public Structure(int num) { this->field = num; } } Structure myStructure(25); myStructure.field; // <-- 25 Помимо конструктора, в структуре можно определить любой другой метод. Структуры относятся к типам-значений (на ряду с интами, чарами итд), т.е. размещается структура в стеке. По сути, структура это класс лишенный возможности наследования, но, например, в C# структура может реализовывать интерфейс.
Как ты собрался инкапсулировать структуру, если я к примеру начну вмешиваться в процесс и изменять ее динамически добавляя: свойства, методы и изменять поведение? Есть такая штука может поможет. Давай осваиваться на том, для каких целей тебе это нужно и что ты пытаешься добиться от php? Может все же будет проще создать динамический класс (структуру) - финализировать и инкапсулировать ее.
хех... это ж мечта! Ещё она должна быть с сильной типизацией, что бы пыхомашина могла все это аккуратно и компактно разложить в памяти без лишнего оверхеда. В свое время пришлось писать сервис на go, т.к. пых на той же задаче отожрал неприлично много оперативки, а go уложился в приемлемые 50 мегабайт, что было даже меньше, чем я расчитывал.
Как ты добавишь метод?? Структуры чаще всего нужны, что бы объединить несколько полей. Как DTO'шки. К тому же, с инкапсуляцией проблем нет, поля можно сделать приватными и определить геттеры/сеттеры. Я хочу сделать альтернативу массиву с фиксированной структурой. Щас поясню. Вернув массив, я по сути не знаю какие там в нем данные, IDE'шка мне не подскажет. Но, если вернуть структуру, где каждое поле четко регламентировано, я буду точно знать какие данные мне доступны! На данный момент так и есть. Проще создать класс, который будет висеть в глобальной области видимости все время жизни приложения, и который будет использован в паре мест в 1-2 классах. Это как история с генераторами. Без них можно (юзай итераторы), но с ними гораздо удобнее. Так же и структуры, как альтернатива классам. --- Добавлено --- Ну вот подождем когда сделают typed properties, без них и мечтать не стоит о таком.
Что это будет за структура такая, которая даже калбеки не поддерживает? Что если в массиве прилетит набор анонимных функций, что тогда, запретить юзать и урезать на хер возможности замыканий? Если ты будешь делать это динамически - то не так ,не так тебе среда не подскажет, что ты делал или делаешь. Ты будешь видеть только как собирается структура и по какому принципу работает ее алгоритм (который ты собственно хочешь реализовать).
@rodent90, я подозреваю, что мы говорим о 2 разных понятиях. Вот, сперва почитай про те структуры, о которых мы тут говорим https://msdn.microsoft.com/ru-ru/library/0taef578.aspx
Sergey108, а так ты хочешь это расширением для php разработать? Не путай два разных языка. Я тебе говорю как будет более оптимально решить задачу, нежели писать велосипед.
@rodent90, я хочу это сделать частью языка. Нужно лишь составить грамотное RFC и отдать на голосование. Ни о каких велосипедах речи не идет. Тут обсуждаются структуры, как часть языка.
Нет в php struct - типа значений (только если вмешиваться через zval* или же писать свое расширение). Есть трейты и классы. Которыми как-раз без труда можно решить эту задачу.
@rodent90, ты не в курсе, что можно делать RFC? https://wiki.php.net/rfc/howto Откуда по твоему все эти модные плюшки типо тайп хинтов, генераторов итд? Неужели разработчикам вздумалось и они никого не спросив это сделали? НЕТ! На каждую фичу был оформлен RFC. Вот и я хочу сделать RFC, что бы в будущем увидеть структуры (в 7.2 хотелось бы, на 7.1 уже опоздали).
Структуры не наследуются (да, да, final class скажете вы, и я соглашусь), хранятся в стеке (передаются по значению), могут быть объявлены локально (прямо в функции или методе). Было бы здорово, если можно было бы объявить структуру на уровне класса, как и разрешить структурам реализовывать интерфейсы, как в C#. Короче, нет предела мечтаниям.
Sergey108, ты либо заблудился, либо не понимаешь о чем пишешь. Давай рассмотрим поведение переменных в php: PHP: $a = "a"; А на самом деле это: Код (Text): a: { type: string, value: str: val: "a" len: 1 is_ref: 0 refcount: 1 } Принцип построения: Код (Text): struct zval { zvalue_value value; zend_uchar type; zend_uchar is_ref; zend_ushort refcount; }; Так вот об этом дано выше, как примерно можно сделать такое детище, но гемороя ты выхватишь довольно много, да и это того стоить не будет, когда проще юзнуть класс и сделать динамику для строения структур, а не только одной конкретно. Тоже самое тебя ждет и в построении Enum, если вдруг взбредет делать это на php, могу посоветовать сделать дефайном через константы и можно попробовать еще завязаться на пространствах имен.
@rodent90, я тебя не понимаю. Тема не о внутренностях PHP, внутренности меня не интересуют, оставим их разрабам. Я хочу услышать мнение людей по поводу структур, как самостоятельной конструкции (на ровне с классами, трейтами, интерфейсами). И ищу единомышленников, которые помогут составить RFC. А там уже видно будет, примут - так будут структуры, не примут - ну значит действительно не нужны они.
Ну вот final и clone решают основные отличия. Локальность можно решить неймспейсами, хотя (мое мнение) локальность структур - редкоиспользуемый вариант. Интерфейсы есть. В общем неудобство одно - делать clone... что-то мне не кажется, что ради одного такого стоит городить отельные синтаксические конструкции для структур
Давай покажу на примере. Спойлер: гипотетический код PHP: <?php class File { /** @var File::Meta */ private $meta; public struct Meta { public function __construct(array $meta) { $this->stream_type = $meta['stream_type']; $this->wrapper_type = $meta['wrapper_type']; $this->uri = $meta['uri']; // ... } public $stram_type; public $wrapper_type; public $uri; // ... } public function __construct(string $filename) { $handler = fopen($filename, 'r+'); $meta = stream_get_meta_data($handler); $this->meta = new Meta($meta); } public function getMeta(): Meta { return $this->meta; } } // без конструктора class File { /** @var File::Meta */ private $meta; public struct Meta { public $stram_type; public $wrapper_type; public $uri; // ... } public function __construct(string $filename) { $handler = fopen($filename, 'r+'); $meta = stream_get_meta_data($handler); $this->meta = new Meta { $meta['stream_type'], $meta['wrapper_type'], $meta['uri'] }; } public function getMeta(): Meta { return $this->meta; } } получаем еще 1 инструмент для структурирования кода. Хотя с таким успехом лучше предложить внутренние классы. Чето я сам засомневался в полезности структур. Надо еще раз хорошенько подумать.
Чутка поразмыслил. Все таки со структурами (уровня класса) удобно. Если использовать класс как структуру, то чаще всего класс будет содержать только кучку публичных свойств. Класс все же ООПшная штука. Преимущества структур: 1. Удобный способ упаковать несколько значений. 2. Структуры передаются по значению. Что гарантирует, что данные типа значения будут скопированы при передаче структуры. 3. Структура может быть как составная часть класса. А с приватной областью видимости доступна только классу. Но если впилить в язык вложенные классы, то по сути, необходимость структур пропадает. Единственное, класс это ссылочный тип. @MiksIr, куча файликов с классами, в которых всего несколько свойств, как то не очень. Структуры удобней. Но настоящее удобство структур это возможность объявления в классе, с модификаторами доступа. --- Добавлено --- Вот что-что но пользы было бы больше чем от анонимных классов. Для чего они их вообще ввели!?
ООП никак не исключает наличия существования DTO, о которых тут, в общем, и идет речь. Решается, на самом деле, так, как это решено в DTO. Т.е. immutable. К сожалению, этого нет в пхп, но эмулируется магией + гетеры/сетеры. И в общем immutable - это правильный путь со многих точек зрения. Мне кажется, вы уже пытаетесь какие-то абстрактные случаи выдумать. Структура внутри класса? Мне кажется такой класс хороший кандидат на код ревью на предмет нарушения SRP