Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions tip_dannih_zval/privedenie_tipov_i_operatsii.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Приведение типов и операции

##Базовые операци
##Базовые операции

Так как zval-ы это комплекстные значения вы не можете напрямую выполнять над ними такие операции как `zv1 + zv2`. Если вы попробуете выполнить что-то подобное, то либо получите ошибку, либо получите сложение двух указателей, а не их значений.

Expand Down Expand Up @@ -44,7 +44,7 @@ int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); /* < */
int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); /* <= */
```
Все функции принимают в качестве аргумента zval `result`, в которой будет сохранен результат операции над операндами `op1` и `op2`. Результат возвращаемый функциями (`SUCCESS` или `FAILURE`) сообщает о том была операция произведена успешно или нет. Помните, что переменной `result` всегда устанавливается какое-то значения, вне зависимости от того успешно завершилась операцция или нет.
Все функции принимают в качестве аргумента zval `result`, в которой будет сохранен результат операции над операндами `op1` и `op2`. Результат возвращаемый функциями (`SUCCESS` или `FAILURE`) сообщает о том была операция произведена успешно или нет. Помните, что переменной `result` всегда устанавливается какое-то значения, вне зависимости от того успешно завершилась операция или нет.

Переменной `result` должна быть выделена память и она должна быть инициализирована перед вызовом одной из перечисленных выше функций. Как альтенатива, переменные `result` и `op1` могут быть одной и той же переменной, в таком случае будет выполнена эффективная операция составного присваивания:
```c
Expand Down Expand Up @@ -121,17 +121,17 @@ int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
```
Еще раз подчеркнем: все функции принимают на вход 2 операнда, zval `result`, в который будет записан результат и возвращают `SUCCESS`/`FAILURE`.

Функция `compare_function()` выполняет "обычное" в терминах PHP сравнение (то естбь ведет себя так же как и операторы `<`, `>` и `==`)performs a “normal” PHP comparison (i.e. it behaves the same way as the <, > and == operators). Функция `numeric_compare_function()` сравнивает операнды как числа (первым делом приводя их типы к double).
Функция `compare_function()` выполняет "обычное" в терминах PHP сравнение (то есть ведет себя так же как и операторы `<`, `>` и `==`). Функция `numeric_compare_function()` сравнивает операнды как числа (первым делом приводя их типы к double).

Функций `string_compare_function_ex()` сравнивает операнды как строки и меет флаг отвечающий за то должны ли строки сравниваться без учета регистра букв. Также, вместо того чтобы задавать этот флаг вы можете воспользоваться функциями `string_compare_function()` (регистрозависимое сравнение) или `string_case_compare_function()` (регистронезависимое сравнение). Переменные сравниваются этими функциями как обычные строки без дополнительной магии для чисел представленных как строки.
Функций `string_compare_function_ex()` сравнивает операнды как строки и имеет флаг, отвечающий за то, должны ли строки сравниваться без учета регистра букв. Также, вместо того чтобы задавать этот флаг вы можете воспользоваться функциями `string_compare_function()` (регистрозависимое сравнение) или `string_case_compare_function()` (регистронезависимое сравнение). Переменные сравниваются этими функциями как обычные строки без дополнительной магии для чисел представленных как строки.

Функция `string_locale_compare_function()` выполняет сравнение строк в соответствии с текущей локалью, эта функция доступна только если определен макро `HAVE_STRCOLL`. По этому вы должны делать проверку `#ifdef HAVE_STRCOLL` прежде чем использовать эту функцию. Лучше избегать использования этой функции..
Функция `string_locale_compare_function()` выполняет сравнение строк в соответствии с текущей локалью, эта функция доступна только если определен макрос `HAVE_STRCOLL`. Поэтому вы должны делать проверку `#ifdef HAVE_STRCOLL` прежде чем использовать эту функцию. Лучше избегать использования этой функции..

##Приведение типов

При реализации своего кода вы часто будете работать с одними и теми же типами zval-ов. Например, если вы пишите код обрабатывающий строки, то вы можете захотеть работать только с строковыми zval-ами и не беспокоиться о всех остальных типах. С другой стороны вы можете захотеть поддерживать систему динамических типов PHP, которая позволяет работать с числами как со строками. Расширениям следует поддерживать систему динамических типов.

Для поддержки системы динамических типов вам следует преобразовывать ваши zval-ы к тем типам, с которыми вы собираетесь работать. Для этой цели PHP поедрставляет функции `convert_to_*` для каждого типа (кроме ресурсов, так как не существует тайп кастинга (resource)):
Для поддержки системы динамических типов вам следует преобразовывать ваши zval-ы к тем типам, с которыми вы собираетесь работать. Для этой цели PHP предоставляет функции `convert_to_*` для каждого типа (кроме ресурсов, так как не существует тайп кастинга (resource)):
```c
void convert_to_null(zval *op);
void convert_to_boolean(zval *op);
Expand Down Expand Up @@ -289,7 +289,7 @@ if (tmp_zval_used) {
```
Второй аргумент в этой функции — указатель не временный zval, третий — указатель на integer. Если эта функция использовала внутри себя временный zval, то она установит третий аргумент в единицу, иначе — в ноль.

Основываясь на значении `tmp_zval_used` вы можете решить использовать оригинальный zval или временную купию. Удобно присвоить значение временного zval-а оригинальному при помощи `zv_ptr = &tmp_zval`. Это позволит вам всегда работать с `zv_ptr` вместо того чтобы везде использовать условие для выбора одного из 2 значений.
Основываясь на значении `tmp_zval_used` вы можете решить использовать оригинальный zval или временную копию. Удобно присвоить значение временного zval-а оригинальному при помощи `zv_ptr = &tmp_zval`. Это позволит вам всегда работать с `zv_ptr` вместо того чтобы везде использовать условие для выбора одного из 2 значений.

В конце вам нужно вызвать деструктор для временного zval-а `zval_dtor(&tmp_zval)`, но только если он действительно использовался.

Expand Down