Почему некоторые функции php «возвращают» заданный параметр?

#php #function

#php #функция

Вопрос:

Я не уверен, правильно ли я сформулировал этот вопрос, но я не знаю, как еще его сформулировать, не приводя примеров, что я и сделаю.

Примеры:

прег_матч

 preg_match("/d{4}-d{2}-d{2}Td{2}:d{2}:d{2}/", $input_line, $output_array);
  

Почему мы присваиваем preg_match параметр $output_array ? Кажется, это не имеет смысла в контексте того, как работает остальная часть php. Разве следующее не было бы более общепринятым?

 $output_array = preg_match("/d{4}-d{2}-d{2}Td{2}:d{2}:d{2}/", $input_line);
  

openssl_private_encrypt — шифрование

 openssl_private_encrypt ($data , $encrypted_data , $key);
  

Опять же, почему мы передаем $encrypted_data функции? Вместо того, что делают 99% других функций, и возвращает результат, который может быть использован для установки значения переменной.

 $encrypted_data = openssl_private_encrypt ($data, $key);
  

Является ли это унаследованной проблемой? Есть ли веские причины для того, чтобы делать это с определенными функциями?

Комментарии:

1. Сначала вы должны разделить две вещи: результат, независимо от того, совпадает регулярное выражение или нет, что возвращается и что имеет смысл с лингвистической точки зрения: «если preg совпадает, то …». И, с другой стороны, необязательный массив захвата. Как бы вы хотели выразить тот факт, что это необязательно в противном случае? Вам нужно было бы определить сигнатуру функции таким образом, чтобы она возвращала «смешанный» тип, кошмар для всех программистов, поскольку тип результата зависит от ввода, а не от реализации!

2. @MarkBaker … хммм, глядя на документы, это 1 (совпадение) 0 (нет совпадения) или FALSE (что-то пошло не так) — что, вероятно, вызовет ошибку, я бы предположил… итак, это значение int или boolean. Должен любить php, у него есть «характер»

3. PHP написан на C, и в C был своего рода «стандарт», когда дело доходит до сообщения об ошибках, в котором все функции возвращают код состояния, а фактическое возвращаемое значение передается как указатель аргумента. Я предполагаю, что люди, работающие над этими функциями PHP, думали, что было бы разумно, если бы сам PHP следовал тому же соглашению.

4. Потому что PHP — довольно неаккуратно разработанный язык и потому что он собрал много мусора за эти годы. Он также имеет тенденцию предоставлять API библиотек, которые он использует, напрямую копируя соглашения о вызовах этого API. preg_match отражает интерфейс библиотеки PCRE, тогда как openssl_private_encrypt отражает интерфейс библиотеки OpenSSL.

5. @GordonM А теперь объясните, почему эти библиотеки выбрали именно этот интерфейс … :o)

Ответ №1:

Поскольку PHP не силен в создании исключений в старой доброй стандартной библиотеке core, ему нужен другой механизм, чтобы различать два аспекта работы функции:

  • удалась ли операция?
  • каково возвращаемое значение, если таковое имеется?

Языки, которые в большей степени основаны на исключениях, имели бы что-то вроде этого:

 try:
    value = somefunc()
except SomeError:
    # handle failure
  

Такие языки, как Go, возвращают возвращаемое значение и индикатор состояния ошибки:

 value, err := somefunc()
if err != nil {
    log.Fatal(err)
}
  

Вместо этого PHP использует return значение в качестве индикатора успеха и параметр по ссылке в качестве возвращаемого значения, особенно когда это возвращаемое значение не всегда представляет интерес:

 if (!somefunc($value)) {
    // handle failure
}
echo $value;
  

В противном случае код должен был бы выглядеть примерно так:

 $value = somefunc();
if ($value === false) {
    // handle failure
} else if ($value === 0) {
    // no match
}
echo $value;
  

В некоторых случаях использование возвращаемого значения как для указания ошибки, так и возвращаемого значения невозможно, поскольку false или 0 или оба могут быть допустимым возвращаемым значением, и вы не смогли бы отличить его от кода ошибки. Использование параметров по ссылке для «вторичных» возвращаемых значений не является ужасным дизайнерским решением, если вы не собираетесь использовать исключения.

Комментарии:

1. Это не имеет ничего общего с исключениями. Если регулярное выражение не соответствует, это не исключение или ошибка, оно просто не соответствует, что является прекрасным результатом. Проверьте комментарий @arkasha’s выше, который imo является ответом на этот вопрос.

2. @giorgio Я иллюстрирую разницу между возвращаемым значением и указанием на то, что произошла ошибка , и что для обоих нужны отдельные механизмы сигнализации. Я целенаправленно использую неопределенное somefunc , не preg_match . То, как эта концепция применяется к отдельным функциям, остается на усмотрение отдельного API. FWIW, preg_match также может возвращать false одно из своих возможных возвращаемых значений, что действительно должно быть исключением.

3. Сказав все это, PHP не совсем яркий пример отличного и / или последовательного дизайна API…

4. Читая ответы до сих пор, @deceze ваш ответ имеет наибольший смысл. При сравнении с другими функциями php, которые имеют поведение, которое я описываю, ваш ответ подходит. PHP пытается сигнализировать о двух вещах одновременно, используя один и тот же метод, вместо того, чтобы использовать исключения для сигнализации сбоев.

5. «Сказав все это, PHP не совсем яркий пример отличного и / или последовательного дизайна API …» … Я смотрю на вас $GLOBALS без вашего маленького подчеркивания!