Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: f8daf39a80
Fetching contributors…

Cannot retrieve contributors at this time

file 158 lines (127 sloc) 5.491 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2006 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.0 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_0.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Sara Golemon <pollita@php.net> |
| Modified by Dmitry Zenovich <dzenovich@gmail.com> |
+----------------------------------------------------------------------+
*/

/* $Id$ */

#include "php_runkit.h"

#ifdef PHP_RUNKIT_MANIPULATION
/* {{{ php_runkit_remove_inherited_methods */
static int php_runkit_remove_inherited_methods(zend_function *fe, zend_class_entry *ce TSRMLS_DC)
{
char *function_name = fe->common.function_name;
int function_name_len = strlen(function_name);
zend_class_entry *ancestor_class = php_runkit_locate_scope(ce, fe, function_name, function_name_len);

if (ancestor_class == ce) {
return ZEND_HASH_APPLY_KEEP;
}

zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_clean_children_methods, 4, ancestor_class, ce, function_name, function_name_len);

PHP_RUNKIT_DEL_MAGIC_METHOD(ce, fe);

return ZEND_HASH_APPLY_REMOVE;
}
/* }}} */

/* {{{ proto bool runkit_class_emancipate(string classname)
Convert an inherited class to a base class, removes any method whose scope is ancestral */
PHP_FUNCTION(runkit_class_emancipate)
{
zend_class_entry *ce;
char *classname;
int classname_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/", &classname, &classname_len) == FAILURE) {
RETURN_FALSE;
}

if (php_runkit_fetch_class(classname, classname_len, &ce TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}

if (!ce->parent) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Class %s has no parent to emancipate from", classname);
RETURN_TRUE;
}

zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)php_runkit_remove_inherited_methods, ce TSRMLS_CC);

RETURN_TRUE;
}
/* }}} */

/* {{{ php_runkit_inherit_methods
Inherit methods from a new ancestor */
static int php_runkit_inherit_methods(zend_function *fe, zend_class_entry *ce TSRMLS_DC)
{
char *function_name = fe->common.function_name;
int function_name_len = strlen(function_name);
zend_class_entry *ancestor_class = php_runkit_locate_scope(ce, fe, function_name, function_name_len);

if (zend_hash_exists(&ce->function_table, function_name, function_name_len + 1)) {
return ZEND_HASH_APPLY_KEEP;
}

zend_hash_apply_with_arguments(RUNKIT_53_TSRMLS_PARAM(EG(class_table)), (apply_func_args_t)php_runkit_update_children_methods, 5, ancestor_class, ce, fe, function_name, function_name_len);

PHP_RUNKIT_FUNCTION_ADD_REF(fe);

/* method name keys must be lower case */
function_name = estrndup(function_name, function_name_len);
php_strtolower(function_name, function_name_len);
if (zend_hash_add_or_update(&ce->function_table, function_name, function_name_len + 1, fe, sizeof(zend_function), NULL, HASH_ADD) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error inheriting parent method: %s()", fe->common.function_name);
efree(function_name);
return ZEND_HASH_APPLY_KEEP;
}
efree(function_name);

PHP_RUNKIT_ADD_MAGIC_METHOD(ce, fe->common.function_name, fe);

return ZEND_HASH_APPLY_KEEP;
}
/* }}} */

/* {{{ proto bool runkit_class_adopt(string classname, string parentname)
Convert a base class to an inherited class, add ancestral methods when appropriate */
PHP_FUNCTION(runkit_class_adopt)
{
zend_class_entry *ce, *parent;
char *classname, *parentname;
int classname_len, parentname_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s/s/", &classname, &classname_len, &parentname, &parentname_len) == FAILURE) {
RETURN_FALSE;
}

if (php_runkit_fetch_class(classname, classname_len, &ce TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}

if (ce->parent) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Class %s already has a parent", classname);
RETURN_FALSE;
}

if (php_runkit_fetch_class(parentname, parentname_len, &parent TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}

zend_hash_apply_with_argument(&parent->function_table, (apply_func_arg_t)php_runkit_inherit_methods, ce TSRMLS_CC);

RETURN_TRUE;
}
/* }}} */

#endif /* PHP_RUNKIT_MANIPULATION */

#ifdef ZEND_ENGINE_2
/* {{{ proto int runkit_object_id(object instance)
Fetch the Object Handle ID from an instance */
PHP_FUNCTION(runkit_object_id)
{
zval *obj;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
RETURN_NULL();
}

RETURN_LONG(Z_OBJ_HANDLE_P(obj));
}
/* }}} */
#endif /* ZEND_ENGINE_2 */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
Something went wrong with that request. Please try again.