JFF

PHP: Cannot determine default value for internal functions

Зашла речь про небезызвестный htmlspecialchars, но не просто у нем, а о нем и о работе с htmlentities. Если передать в этот метод строку с этими энтитями, то получим двойное перекодирование.

echo htmlspecialchars('"текст"');
"текст"

Именно для того, чтобы избежать подобного был добавлен параметр double_encode, который по дефолту всегда true.

Но речь не об этом.

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

На ум приходит использовать рефлексию для получения дефолтных значений и передачи их в функцию. Но не все так просто.

Сначала напишем код, который будет вызывать функции принимая в качестве параметра ассоциативный массив с онными.

function call_user_func_params(callable $func, array $params = array()) {
	if (!is_callable($func)) {
		throw "func is not callable";
	}
	$reflection = new ReflectionFunction($func);
	$funcParams = array();

	foreach ($reflection->getParameters() as $parameter) {
		$name = $parameter->getName();

		if (__DEBUG__) {
			var_dump($parameter->getName());
			var_dump($parameter->isOptional());
		}

		if (array_key_exists($name, $params)) {
			array_push($funcParams, $params[$name]);
		} elseif ($parameter->isOptional()) {
			array_push($funcParams, $parameter->getDefaultValue());
		} else {
			throw new Exception("Value for parameter {$name} not found");
		}
	}
	return call_user_func_array($func, $funcParams);
}

А теперь воспользуемся ей.

function foo($bar = 'bar', $baz = 'baz') {
	echo "{$bar}, {$baz}\n";
}

call_user_func_params('foo', array('baz' => 'xyz'));

Выводит то, что и ожидалось.

bar, xyz

А теперь так.

call_user_func_params('htmlspecialchars', array('string' => ""текст"", 'double_encode' => false));

Облом-с.

PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Cannot determine default value for internal functions' in file.php

А все потому, что пхп обрабатывает встроенные функции иначе, нежели написанные кривыми руками программиста.🙂

А еще документация нас открыто уведомляет о том, что именя параметров реальные (я про встроенные функции) могут отличаться от того, что написано в спецификации.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s