Rfc php что такое

Rfc php что такое

Newcomers to PHP core development should read The Mysterious PHP RFC Process and How You Can Change the Web before starting the RFC process.

If you don’t have the skills to fully implement your RFC and no-one volunteers to code it, there is little chance your RFC will be successful. To learn about PHP core development see References about Maintaining and Extending PHP.

Email internals@lists.php.net to measure reaction to your intended proposal. State who would implement the feature, or whether the proposal is only a “concept”. Proceed with an RFC if feedback is not negative or if a detailed RFC will clarify the proposal. Mail list subscription is at http://php.net/mailing-lists.php. (Reminder: always «bottom post» your replies. Never “top post”.)

Get wiki RFC karma (this is only required if you don’t have a VCS account for php.net. PHP developers can log on with their credentials and already have the necessary karma to create RFCs):

Email internals@lists.php.net requesting RFC karma for your wiki account. In the email, remind people about the RFC you plan to create. Note that RFC karma does not automatically give you karma to vote. See https://wiki.php.net/rfc/voting#rfc_proposer

Listen to the feedback, and try to answer/resolve all questions. Update your RFC to document all the issues and discussions. Cover both the positive and negative arguments. Put the RFC URL into all your replies.

When discussion ends, and a minimum period of two weeks has passed since you mailed internals@lists.php.net in step 4, consider one day heads up mail on the mailing list and then you can move your RFC to “Voting” status. There should be no open questions in the RFC . Review https://wiki.php.net/RFC/voting#voting first. Consider whether the feature concept should be voted on before you invest time in implementation. Or perhaps an implementation is needed to show the feature is feasible; in this case, make it clear whether or not the current implementation is being voted on.

Add the voting start and end dates to the text of the RFC , including the time and timezone that the voting will end.

Send an email to internals@lists.php.net announcing the start of voting for your RFC . Start a new mail thread and put “[VOTE] < RFC Title>” in the subject. Set a deadline for voting; the minimum period is two weeks.

Your RFC is accepted: update the status of your RFC page and its section on https://wiki.php.net/RFC to “Accepted” and close the vote via changing closed=“false” to closed=“true” in the voting macro. When the code is merged, update the RFC and section to state which PHP version the code was merged into.

Your RFC is declined: update the status of your RFC page and its section on https://wiki.php.net/RFC to “Declined” and close the vote via changing closed=“false” to closed=“true” in the voting macro.

Читайте также:  Install php curl ssl

A serious issue with your RFC needs to be addressed: update the status of your RFC page and its section on https://wiki.php.net/RFC to “Under Discussion” and continue again from step 5.

Notes

Open new RFCs rather than re-use existing documents

In general the status of an RFC should not be moved backwards to an earlier status. In practice there will be times when people accidentally open the voting too early, or some serious problem is found with an RFC during the voting phase, in those cases it’s fine to move the status back until the problem is fixed. But as a rule, leaving each RFC document with a clear history of what happened to that RFC makes it easier to understand past discussions.

Also, we have rules about when RFCs are allowed to be put into voting. If a RFC document has been re-used there could be some confusion about when it is allowed to be put to a vote.

Leaving the previous RFC document intact, with the results of a vote if one was taken, leaves a clearer document trail than if the document has been recycled.

It can also be useful to create a new RFC document when an RFC changes significantly during it’s discussion. Although previous versions of documents are available through the wiki, finding where an RFC was re-written and trying to understand why it was, are quite difficult. Leaving the previous version intact, with a note pointing to the new version makes understanding discussion history much easier.

RFCs ‘belong’ to a single author

Although minor typos can be fixed by other people, any significant changes should be approved by the original RFC author.

If you wish to ‘take over’ an RFC , you need the express consent of the RFC author. If you can’t get that consent, for example the person doesn’t respond, then please open a new RFC document.

Don’t list someone as an author without their express consent

There have been cases where someone has added someone’s name as an author of an RFC , and this has caused drama as the person wasn’t aware that they had been added.

If you want to credit someone for having done a large amount of work, e.g. when taking over an abandoned RFC , you can do that by adding the phrase ‘based on work by’ e.g. “Author: Danack, based on work Anthony Ferrara”. Though people are free to ask for their name to be removed even in that case.

Источник

О дженериках в PHP и о том, зачем они нам нужны

В этой статье мы рассмотрим некоторые распространённые проблемы, связанные с массивами в PHP. Все проблемы могут быть решены с помощью RFC, добавляющего в PHP дженерики. Мы не будем сильно углубляться в то, что такое дженерики, но к концу статьи вы должны понять, чем они полезны и почему многие так ждут их появления в PHP.

Допустим, у вас есть набор блог-постов, скачанных из какого-то источника данных.

Вам нужно циклически пройти по всем постам и что-то сделать с их данными. Например, с id .

foreach ($posts as $post) < $id = $post->getId(); // Что-то делаем >

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

Читайте также:  Java calendar add seconds

Целостность структуры данных (Data integrity)

В PHP массив представляет собой коллекцию . элементов.

$posts = [ 'foo', null, self::BAR, new Post('Lorem'), ];

Если циклически пройти по нашему набору постов, то в результате получим критическую ошибку.

PHP Fatal error: Uncaught Error: Call to a member function getId() on string

Вызываем ->getId() применительно к строке ‘foo’ . Не прокатило. При циклическом проходе по массиву мы хотим быть уверены, что все значения принадлежат к определённому типу. Можно сделать так:

foreach ($posts as $post) < if (!$post instanceof Post) < continue; >$id = $post->getId(); // Что-то делаем >

Это будет работать, но если вы уже писали PHP-код для production, то знаете, что такие проверки иногда быстро разрастаются и загрязняют кодовую базу. В нашем примере можно проверять тип каждой записи в методе ->find() в $blogModel . Но это лишь переносит проблему из одного места в другое. Хотя ситуация чуть улучшилась.

С целостностью структуры данных есть ещё одна сложность. Допустим, у вас есть метод, которому нужен массив блог-постов:

function handlePosts(array $posts) < foreach ($posts as $post) < // . >>

Мы опять можем добавить в цикл дополнительные проверки, но это не гарантирует, что $posts содержит только коллекцию постов Posts.

Начиная с PHP 7.0 для решения этой проблемы вы можете использовать оператор . :

function handlePosts(Post . $posts) < foreach ($posts as $post) < // . >>

Но у этого подхода есть обратная сторона: вам придётся вызывать функцию применительно к распакованному массиву.

Производительность

Можно предположить, что лучше заранее знать, содержит ли массив только элементы определённого типа, чем потом в каждом цикле каждый раз вручную проверять типы.

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

Автозавершение (Code completion)

Не знаю, как вы, а я при написании PHP-кода прибегаю к IDE. Автозавершение чрезвычайно повышает продуктивность, так что я хотел бы использовать его и здесь. При циклическом проходе по постам нам нужно, чтобы IDE считал каждый $post экземпляром Post . Давайте посмотрим на простую PHP-реализацию:

# BlogModel public function find() : array < // возвращает . >

Начиная с PHP 7.0 появились типы возвращаемых значений, а в PHP 7.1 они были улучшены с помощью void и типов, допускающих значение null. Но мы никак не можем сообщить IDE, что содержится в массиве. Поэтому мы возвращаемся к PHPDoc.

/** * @return Post[] */ public function find() : array < // возвращает . >

При использовании реализации «дженерика», например класса моделей (model class), не всегда возможен подсказывающий метод ->find() . Так что в нашем коде придётся ограничиться подсказывающей переменной $posts.

/** @var Blog[] $posts */ $posts = $blogModel->find();

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

На мой взгляд, такое решение — дженерики. Не буду подробно расписывать, что они делают, об этом вы можете почитать в RFC. Но я приведу пример того, как дженерики могут помочь в решении вышеописанных проблем, всегда обеспечивая наличие в коллекции корректных данных.

Читайте также:  Html убрать пробелы между изображениями

Важное замечание: дженериков пока что нет в PHP. RFC предназначен для PHP 7.1, о его будущем нет никакой дополнительной информации. Нижеприведённый код основан на интерфейсах Iterator и ArrayAccess, которые существуют с PHP 5.0. В конце мы разберём пример с дженериками, представляющий собой фиктивный код.

Для начала создадим класс Collection , который работает в PHP 5.0+. Этот класс реализует Iterator , чтобы можно было циклически проходить по его элементам, а также ArrayAccess , чтобы можно было использовать «массивоподобный» синтаксис для добавления элементов коллекции и обращения к ним.

class Collection implements Iterator, ArrayAccess < private $position; private $array = []; public function __construct() < $this->position = 0; > public function current() < return $this->array[$this->position]; > public function next() < ++$this->position; > public function key() < return $this->position; > public function valid() < return isset($this->array[$this->position]); > public function rewind() < $this->position = 0; > public function offsetExists($offset) < return isset($this->array[$offset]); > public function offsetGet($offset) < return isset($this->array[$offset]) ? $this->array[$offset] : null; > public function offsetSet($offset, $value) < if (is_null($offset)) < $this->array[] = $value; > else < $this->array[$offset] = $value; > > public function offsetUnset($offset) < unset($this->array[$offset]); > >

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

$collection = new Collection(); $collection[] = new Post(1); foreach ($collection as $item) < echo "getId()>\n"; >

Обратите внимание: нет никакой гарантии, что $collection содержит только Posts . Если добавить, к примеру, строковое значение, то работать будет, но наш цикл сломается.

$collection[] = 'abc'; foreach ($collection as $item) < // This fails echo "getId()>\n"; >

При текущем уровне развития PHP мы можем решить эту проблему с помощь создания класса PostCollection . Обратите внимание: типы возвращаемых данных, допускающие использование null, доступны лишь с PHP 7.1.

class PostCollection extends Collection < public function current() : ?Post < return parent::current(); >public function offsetGet($offset) : ?Post < return parent::offsetGet($offset); >public function offsetSet($offset, $value) < if (!$value instanceof Post) < throw new InvalidArgumentException("value must be instance of Post."); >parent::offsetSet($offset, $value); > >

Теперь в нашу коллекцию могут добавляться только Posts .

$collection = new PostCollection(); $collection[] = new Post(1); // This would throw the InvalidArgumentException. $collection[] = 'abc'; foreach ($collection as $item) < echo "getId()>\n"; >

Работает! Даже без дженериков! Есть только одна проблема: решение немасштабируемое. Вам нужны отдельные реализации для каждого типа коллекции, даже если классы будут различаться только типом.

Вероятно, создавать подклассы можно с бо́льшим удобством, «злоупотребив» поздним статическим связыванием и рефлексивным API PHP. Но вам в любом случае понадобится создавать классы для каждого доступного типа.

Великолепные дженерики

Учитывая всё это, давайте рассмотрим код, который мы могли бы написать, будь дженерики реализованы в PHP. Это может быть один класс, используемый для всех типов. Ради удобства я приведу лишь изменения по сравнению с предыдущим классом Collection , имейте это в виду.

class GenericCollection implements Iterator, ArrayAccess < public function current() : ?T < return $this->array[$this->position]; > public function offsetGet($offset) : ?T < return isset($this->array[$offset]) ? $this->array[$offset] : null; > public function offsetSet($offset, $value) < if (!$value instanceof T) < throw new InvalidArgumentException("value must be instance of ."); > if (is_null($offset)) < $this->array[] = $value; > else < $this->array[$offset] = $value; > > // public function __construct() . // public function next() . // public function key() . // public function valid() . // public function rewind() . // public function offsetExists($offset) . > $collection = new GenericCollection(); $collection[] = new Post(1); // This would throw the InvalidArgumentException. $collection[] = 'abc'; foreach ($collection as $item) < echo "getId()>\n"; >

И всё! Мы используем в качестве динамического типа, который можно проверять перед runtime. И опять же, класс GenericCollection можно было бы брать для любых типов.

Источник

Оцените статью