#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
без вашего маленького подчеркивания!