Статьи

Есть расширение пола для PHP

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

Недавно я углубился в раздел руководства по PHP, в котором перечислены расширения, используемые для помощи с человеческим языком и кодировкой символов . Я никогда не смотрел на них в целом — например, работая с gettext , я всегда как бы приземлялся на него и игнорировал все остальное. Ну, из тех, кто привлек внимание, особенно в наше время, учитывая различные противоречия, — расширение пола .

Розовый и зеленый слон, символизирующий гендерные роли

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

Расширение Gender PHP — это порт программы gender.c Основная цель — выяснить пол имен. Текущая база данных содержит> 40000 имен из 54 стран.

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

Хотя его последний стабильный выпуск был в 2015 году, расширение использует пространства имен, которые четко указывают на то, что это не какой-то давно утерянный пережиток прошлого — были предприняты сравнительно недавние усилия, чтобы привести его в соответствие с современными стандартами кодирования. Даже пример кода использует пространства имен:

 <?php

namespace Gender;

$gender = new Gender;

$name = "Milene";
$country = Gender::FRANCE;

$result = $gender->get($name, $country);
$data = $gender->country($country);

switch($result) {
    case Gender::IS_FEMALE:
        printf("The name %s is female in %s\n", $name, $data['country']);
    break;

    case Gender::IS_MOSTLY_FEMALE:
        printf("The name %s is mostly female in %s\n", $name, $data['country']);
    break;

    case Gender::IS_MALE:
        printf("The name %s is male in %s\n", $name, $data['country']);
    break;

    case Gender::IS_MOSTLY_MALE:
        printf("The name %s is mostly male in %s\n", $name, $data['country']);
    break;

    case Gender::IS_UNISEX_NAME:
        printf("The name %s is unisex in %s\n", $name, $data['country']);
    break;

    case Gender::IS_A_COUPLE:
        printf("The name %s is both male and female in %s\n", $name, $data['country']);
    break;

    case Gender::NAME_NOT_FOUND:
        printf("The name %s was not found for %s\n", $name, $data['country']);
    break;

    case Gender::ERROR_IN_NAME:
        echo "There is an error in the given name!\n";
    break;

    default:
        echo "An error occurred!\n";
    break;

}

Пока у нас есть этот код, давайте посмотрим на него.

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

Например, класс имеет краткие названия стран в качестве констант (например, BRITAINUKGREAT BRITAIN

 $gender = new Gender\Gender;
var_dump($gender->country(Gender\Gender::BRITAIN));

array(2) {
  'country_short' =>
  string(2) "UK"
  'country' =>
  string(13) "Great Britain"
}

Только UKGB То, почему они выбрали этот маршрут, а не полагались на существующий пакет геонам или даже на точный список констант, можно только догадываться.

После использования класс использует метод get Но страна должна быть константой класса (поэтому вам нужно знать ее наизусть или использовать их значения при добавлении в пользовательский интерфейс, поскольку она не будет соответствовать ни одному стандартному списку кодов стран), и она также возвращает целое число — другое константа, определенная в классе, вот так:

 const integer IS_FEMALE = 70 ;
const integer IS_MOSTLY_FEMALE = 102 ;
const integer IS_MALE = 77 ;
const integer IS_MOSTLY_MALE = 109 ;
const integer IS_UNISEX_NAME = 63 ;
const integer IS_A_COUPLE = 67 ;
const integer NAME_NOT_FOUND = 32 ;
const integer ERROR_IN_NAME = 69 ;

Там просто нет рифмы или причины для любого из этих значений.

Другой метод, isNick Это имеет смысл в таких случаях, как Боб против Роберта или Дика против Ричарда, но может ли оно действительно превзойти эти предсказуемые английские значения? Метод вдвойне сбивает с толку, потому что он говорит, что возвращает массив в сигнатуре, тогда как в описании говорится, что это логическое значение.

Неверное описание метода возврата типа

Наконец, метод similarNames Это включает в себя псевдонимы? На чем основано сходство? Марио и Мария похожи, несмотря на то, что они противоположного пола? Или Марио просто похож на Марека? Марио похож на Марека вообще ? Там нет информации.

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

Установка

Я протестировал это в изолированной среде через Homestead Improved с предустановленной PECL.

 sudo pecl install gender
echo "extension=gender.so" | sudo tee /etc/php/7.1/mods-available/gender.ini
sudo phpenmod gender
pear run-scripts pecl/gender

Последняя команда спросит, куда поместить словарь. Я предполагаю, что это там для целей расширения. Я выбрал . , как в «текущей папке». Давайте попробуем сделать это, выполнив простой файл index.php

Милена женщина во Франции

Конечно же, это работает. Хорошо, давайте изменим страну на $country = Gender::CROATIA; ,

Милена женщина в Хорватии

Ладно, конечно, это не обычное имя, и не в том формате, но больше всего похоже на Милену, женское имя в Хорватии. Давайте посмотрим, что похоже на Милену через similar.php

 <?php
namespace Gender;

$gender = new Gender;
$similar = $gender->similarNames("Milena", Gender::CROATIA);

var_dump($similar);

У Милены нет похожих имен?

Не то, что я ожидал. Давайте посмотрим оригинал, Милен.

Милена имеет странное сходство

Итак, Милена указана как имя, похожее на Милен, но Милена не похожа на Милену? Кроме того, кажется, что есть проблемы с кодировкой на двух из них? А в хорватском алфавите даже нет буквы «у», у нас определенно нет ни одного из этих похожих имен, независимо от того, что скрывается под знаком вопроса.

Хорошо, давайте попробуем что-нибудь еще. Давайте посмотрим, является ли Боб псевдонимом Роберта в alias.php

 <?php
namespace Gender;
$gender = new Gender;
var_dump($gender->isNick('Bob', 'Robert', Gender::USA));

Боб - псевдоним Роберта

Действительно, похоже, что это правда. Впрочем, низко висящие фрукты. Давайте посмотрим на местный.

 var_dump($gender->isNick('Tea', 'Dorotea', Gender::CROATIA));

Чай не является псевдонимом Dorotea

Ох, давай.

Как насчет вопроса Марио / Марии / Марека с самого начала? Давайте посмотрим на сходства для них в порядке.

Марио похож на себя и неверно закодированную версию самого себя
Мария похожа на себя и неверно закодирована
Марек похож только на себя

Не хорошо.

Еще пара попыток. Чтобы упростить тестирование, изменим строки $name$countryindex.php

 $name = $argv[1];
$country = constant(Gender::class.'::'.strtoupper($argv[2]));

Теперь мы можем тестировать из CLI без редактирования файла.

Последние несколько попыток. У меня есть подруга из Туниса по имени Манель. Я бы предположил, что ее имя будет использоваться для мужчин в большинстве стран мира, потому что оно заканчивается согласной. Давайте проверим ее и некоторые другие имена.

Не могу найти Тунис

Туниса нет? Возможно, это не задокументировано в руководстве, давайте выведем все определенные константы и проверим.

 // constants.php
<?php

$oClass = new ReflectionClass(Gender\Gender::class);
var_dump($oClass->getConstants());

Пропавшие страны в списке

Нет, похоже, эти документы на месте. На этом этапе я прекращаю играть с этим инструментом.


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

Как это расширение, которое является и неточным, и неполным, и может быть простым классом, попало в руководство по PHP, неясно, но оно показывает, что в ядре PHP еще многое предстоит сделать (я включаю руководство как «ядро»), прежде чем мы повысим репутацию PHP. За 9 лет (девять!) С тех пор, как началась разработка этого порта, не все страны были добавлены во внутренний список, и все же кто-то решил, что это расширение должно быть в руководстве.

У вас есть больше информации об этом расширении? Ты видишь в этом смысл? Какие другие странные расширения или встроенные функции вы нашли в руководстве или в PHP в целом?