Новые книги

О том, почему партнерства в бизнесе, как правило, эффективнее и успешнее бизнесов предпринимателей-одиночек. Объединяя свои сильные стороны (деньги, знания, идеи, умения, связи, средства, патенты – все что угодно), партнеры не только способствуют упрочению своего бизнеса, но и расширяют его возможности. Однако все эти преимущества могут быть быстро уничтожены, если правила взаимодействия партнеров не были прописаны «на берегу». Для бизнеса нет ничего страшнее, чем междоусобные войны владельцев. Зачастую они заканчиваются крахом партнерства – вкупе с нарушенными обещаниями, финансовыми катастрофами и кошмарными судебными спорами.
Что отличает людей, достигающих великолепных результатов в своем деле, от всех прочих? Почему многие из нас остаются крепкими середнячками, тогда как те, с кем мы начинали, становятся профессионалами мирового уровня? Можем ли мы вообще претендовать на что-то выдающееся или это удел избранных? Что определяет наш успех? Образование? Опыт работы? Амбиции? Талант?

Автор этой книги, колумнист и редактор Fortune, уверен: талант (равно как и все вышеперечисленное) здесь ни при чем! Экстраординарные результаты достигаются людьми, которые особым образом практикуются в избранной сфере деятельности — это доказано солидными исследованиями. И эта «осознанная практика», описанная в книге, доступна абсолютно всем.

Перед вами новое российское издание бестселлера Джеффа Колвина. Ранее книга выходила под названием «Выдающиеся результаты. Талант ни при чем!».

Доступ к Аргументам

Учебник РНР
НазадГлава 33. Приём аргументов Вперёд

Доступ к аргументам

Для доступа к аргументам необходимо иметь для каждого аргумента ясно определённый тип. Предельно динамичная природа PHP позволяет прибегать к некоторым трюкам. Поскольку PHP никогда не делает никакой проверки типа, вызыватель может передавать в функции любой вид данных, хотите вы этого или нет. Если вы ожидаете integer, например, вызыватель может передать массив, и наоборот - PHP этого не заметит.

Чтобы работать в этих условиях, вы должны использовать набор API-функций для форсирования конвертации типов каждого передаваемого аргумента (см. Таблицу 9.4).

Примечание: Все функции конвертации ожидают в качестве параметра **zval.

Рисунок 33-3. Таблица 9.4. Функции конвертации аргументов
Функция Описание
convert_to_boolean_ex() Форсирует конвертацию в Boolean. Boolean-значения не изменяются. Long, double и string, содержащие значения 0 и NULL, дают Boolean 0 (FALSE). Массивы и объекты конвертируются на основе количества вхождений или свойств, соответственно. Пустые массивы и объекты конвертируются в FALSE; другие - в TRUE. Все другие значения дают Boolean 1 (TRUE).
convert_to_long_ex() Форсирует конвертацию в long, целочисленный тип по умолчанию. NULL, Boolean, ресурсы и, разумеется, long-значения не изменяются. Double усекаются. String, содержащие integer, конвертируются в соответствующие числовые представления, иначе - дают 0. Массивы и объекты конвертируются в 0, если пустые, иначе - в 1.
convert_to_double_ex()Форсирует конвертацию в double, тип по умолчанию с плавающей точкой. NULL, Boolean, ресурсы, long и double не изменяются. String, содержащие integer, конвертируются в соответствующие числовые представления, иначе - дают 0.0. Массивы и объекты конвертируются в 0.0, если пустые, иначе - в 1.0.
convert_to_string_ex()Форсирует конвертацию в string. String остаются без изменений. NULL конвертируются в пустые строки. Boolean TRUE конвертируются в "1", иначе дают пустую строку. Long и double конвертируются в their соответствующие строковые представления. Массивы конвертируются в строку "Array", а объекты - в строку "Object".
convert_to_array_ex(value)Форсирует конвертацию в массив. Массивы остаются без изменений. Объекты конвертируются в массив с присвоением всех свойств таблице массива. Имена свойств используются как ключи, содержание свойств - как значения. NULL конвертируются в пустой массив. Все другие значения конвертируются в массив, который содержит специфическое исходное значение в элементе с ключом 0.
convert_to_object_ex(value)Форсирует конвертацию в объект. Объекты остаются без изменений. NULL конвертируются в пустой объект. Массивы конвертируются в объекты с ключами как свойствами и значениями свойств как содержимым свойств. Все другие типы дают объект со свойством scalar, имеющим исходное значение в качестве содержимого.
convert_to_null_ex(value)Форсирует типы в NULL, что означает пустой.

Примечание: вы можете найти демо в файле cross_conversion.php на сопутствующем CD-ROM. На Рисунке 9.5 показан вывод.

Рисунок 33-4. Рисунок 9.5. Конвертация в PHP.

Использование этих функций с вашими аргументами гарантирует сохранение типа для всех данных, передаваемых вам. Если предлагаемый тип не соответствует требуемому типу, PHP форсирует содержимое-болванку (пустые строки, массивы или объекты, 0 для числовых значений, FALSE для Boolean), чтобы гарантировать сохранение статуса.

Далее идёт выдержка из модуля-сэмпла, обсуждённого ранее, в которой используются функции конвертации:

zval **parameter;

if((ZEND_NUM_ARGS() != 1) || (zend_get_parameters_ex(1, &parameter) != SUCCESS))
{
    WRONG_PARAM_COUNT;
}

convert_to_long_ex(parameter);

RETURN_LONG(Z_LVAL_P(parameter));

После получения указателя параметра, значение параметра конвертируется в long (integer), которое формирует также return-значение данной функции. Понимание процесса доступа к содержимому значения требует небольшого обсуждения типа zval, определение которого показано в Листинге 9.8.

Рисунок 33-5. Листинг 9.8. Определение PHP/Zend-типа zval.
typedef pval zval;

typedef struct _zval_struct zval;

typedef union _zvalue_value {
	long lval;				/* long-значение */
	double dval;				/* double-значение */
	struct {
		char *val;
		int len;
	} str;
	HashТаблица *ht;			/* значение хэш-таблицы */
	struct {
		zend_class_entry *ce;
		HashТаблица *properties;
	} obj;
} zvalue_value;

struct _zval_struct {
	/* Variable information */
	zvalue_value value;			/* значение */
	unsigned char type;			/* активный тип */
	unsigned char is_ref;
	short refcount;
};

В действительности pval (определённый в php.h) это лишь псевдоним для zval (определённом в zend.h), который, в свою очередь, ссылается на _zval_struct. Это самая интересная структура. _zval_struct это "мастер"-структура, содержащая структуру значения, тип и справочную информацию. Подструктура zvalue_value это union (объединение), содержащее содержимое переменной. В зависимости от типа переменной, вы должны получать доступ к разным членам этого union. Описание обеих структур см. в Таблицах 9.5, 9.6 и 9.7.

Рисунок 33-6. Таблица 9.5. Zend-структура zval
ВхождениеОписание
valueUnion, содержащее содержимое данной переменной. См. описание в Таблице 9.6.
typeСодержит тип переменной. Список доступных типов см. в Таблице 9.7.
is_ref0 означает, что эта переменная не является ссылкой; 1 означает, что эта переменная является ссылкой на другую переменную.
refcount Количество существующих ссылок для данной переменной. Для каждой новой ссылки на значение, хранимое в этой переменной, этот счётчик увеличивается на 1. Для каждой потерянной ссылки - этот счётчик уменьшается на 1. Когда счётчик ссылок достигает 0, для данной переменной больше не существует ни одной ссылке, что вызывает автоматическое освобождение переменной.
Рисунок 33-7. Таблица 9.6. Zend-структура zvalue_value
Используйте это свойство, если переменная имеет тип IS_OBJECT.
ВхождениеОписание
lvalИспользуйте это свойство, если переменная имеет тип IS_LONG, IS_BOOLEAN или IS_RESOURCE.
dvalИспользуйте это свойство, если переменная имеет тип IS_DOUBLE.
strЭта структура может использоваться для доступа к переменным типа IS_STRING. Член len содержит длину строки; член val указывает на саму строку. Zend использует C-строки; таким образом, длина строки включает также ведомый 0x00.
htЭто вхождение указывает на вхождение переменной в хэш-таблице, если переменная является массивом.
obj
Рисунок 33-8. Таблица 9.7. Константы типов Zend-переменных
 
КонстантаОписание
IS_NULLОбозначает NULL (пустое) значение.
IS_LONGЗначение long (integer).
IS_DOUBLEdouble (floating point).
IS_STRINGСтрока.
IS_ARRAYМассив.
IS_OBJECT Объект.
IS_BOOLБулево значение.
IS_RESOURCEРесурс (обсуждение ресурсов см. далее в соответствующем разделе).
IS_CONSTANTКонстантное (определённое) значение.

Для доступа к long вы выполняете доступ к zval.value.lval, для доступа к double вы используете zval.value.dval, и так далее. Поскольку все значения хранятся в union, попытка доступа к данным через некорректный член union приведёт к бессмысленному выводу.

Доступ к массивам и объектам немного сложнее и будет рассмотрен позже.


Назад Оглавление Вперёд
Работа с переменным количеством аргументов/необязательных параметров ВверхРабота с аргументами, передаваемыми по ссылке