Ejemplo n.º 1
0
/**
 * @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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
/**
 * @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;
}