/** * @brief Fetches @a index if it exists from the array @a arr * @param[out] fetched <code>&$arr[$index]</code>; @a fetched is modified only when the function returns 1 * @param arr Array * @param index Index * @return isset($arr[$index]) * @retval 0 Not exists, @a arr is not an array or @a index is of not supported type * @retval 1 Exists * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer * @note $arr[$index] is returned as is: no copying occurs, reference copunt is not updated * @throw E_WARNING if @a offset is not a scalar */ int zephir_array_isset_fetch(zval **fetched, const zval *arr, zval *index, int readonly TSRMLS_DC) { HashTable *h; zval **val; int result; if (Z_TYPE_P(arr) != IS_ARRAY) { *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; } h = Z_ARRVAL_P(arr); switch (Z_TYPE_P(index)) { case IS_NULL: result = zephir_hash_find(h, SS(""), (void**)&val); break; case IS_DOUBLE: result = zend_hash_index_find(h, (ulong)Z_DVAL_P(index), (void**)&val); break; case IS_LONG: case IS_BOOL: case IS_RESOURCE: result = zend_hash_index_find(h, Z_LVAL_P(index), (void**)&val); break; case IS_STRING: result = zend_symtable_find(h, (Z_STRLEN_P(index) ? Z_STRVAL_P(index) : ""), Z_STRLEN_P(index)+1, (void**)&val); break; default: zend_error(E_WARNING, "Illegal offset type"); *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; } if (result == SUCCESS) { *fetched = *val; if (!readonly) { Z_ADDREF_P(*fetched); } return 1; } *fetched = ZEPHIR_GLOBAL(global_null); if (!readonly) { Z_ADDREF_P(*fetched); } return 0; }
/** * Reads class constant from string name and returns its value */ int zephir_get_class_constant(zval *return_value, zend_class_entry *ce, char *constant_name, unsigned int constant_length TSRMLS_DC) { zval **result_ptr; if (zephir_hash_find(&ce->constants_table, constant_name, constant_length, (void **) &result_ptr) != SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Undefined class constant '%s::%s'", ce->name, constant_name); return FAILURE; } ZVAL_ZVAL(return_value, *result_ptr, 1, 0); return SUCCESS; }
/** * @brief Reads an item from @a arr at position @a index and stores it to @a return_value * @param return_value[out] Return value * @param arr Array * @param index Index * @param silent 0 to suppress all warnings, @c PH_NOISY to enable * @return Whether the operation succeeded * @retval @c FAILURE Failure, @a arr is not an array * @retval @c SUCCESS Success * @throw @c E_WARNING if @c arr is not an array and @c silent = @c PH_NOISY * @throw @c E_WARNING if @c index is not of the supported type and @c silent = @c PH_NOISY * @throw @c E_NOTICE if @c index does not exist and @c silent = @c PH_NOISY * @warning @c *return_value should be either @c NULL (preferred) or point to not initialized memory; if @c *return_value points to a valid variable, mmemory leak is possible * @note @c index will be handled as follows: @c NULL is treated as an empty string, @c double values are cast to @c integer, @c bool or @c resource are treated as @c integer */ int zephir_array_fetch(zval **return_value, zval *arr, zval *index, int flags ZEPHIR_DEBUG_PARAMS TSRMLS_DC) { zval **zv; HashTable *ht; int result; ulong uidx = 0; char *sidx = NULL; if (Z_TYPE_P(arr) == IS_ARRAY) { ht = Z_ARRVAL_P(arr); switch (Z_TYPE_P(index)) { case IS_NULL: result = zephir_hash_find(ht, SS(""), (void**) &zv); sidx = ""; break; case IS_DOUBLE: uidx = (ulong)Z_DVAL_P(index); result = zend_hash_index_find(ht, uidx, (void**) &zv); break; case IS_LONG: case IS_BOOL: case IS_RESOURCE: uidx = Z_LVAL_P(index); result = zend_hash_index_find(ht, uidx, (void**) &zv); break; case IS_STRING: sidx = Z_STRLEN_P(index) ? Z_STRVAL_P(index) : ""; result = zend_symtable_find(ht, Z_STRVAL_P(index), Z_STRLEN_P(index)+1, (void**) &zv); break; default: if ((flags & PH_NOISY) == PH_NOISY) { zend_error(E_WARNING, "Illegal offset type in %s on line %d", file, line); } result = FAILURE; break; } if (result != FAILURE) { *return_value = *zv; if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return SUCCESS; } if ((flags & PH_NOISY) == PH_NOISY) { if (sidx == NULL) { zend_error(E_NOTICE, "Undefined index: %ld in %s on line %d", uidx, file, line); } else { zend_error(E_NOTICE, "Undefined index: %s in %s on line %d", sidx, file, line); } } } *return_value = ZEPHIR_GLOBAL(global_null); if ((flags & PH_READONLY) != PH_READONLY) { Z_ADDREF_PP(return_value); } return FAILURE; }