1 /*
2    +----------------------------------------------------------------------+
3    | Yet Another Framework                                                |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.php.net/license/3_01.txt                                  |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Author: Xinchen Hui  <laruence@php.net>                              |
14    +----------------------------------------------------------------------+
15 */
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include "php.h"
22 #include "php_ini.h" /* for zend_alter_ini_entry */
23 #include "Zend/zend_exceptions.h" /* for zend_throw_exception_ex */
24 #include "Zend/zend_interfaces.h" /* for zend_call_method_with_* */
25 
26 #include "php_yaf.h"
27 #include "yaf_namespace.h"
28 #include "yaf_application.h"
29 #include "yaf_dispatcher.h"
30 #include "yaf_router.h"
31 #include "yaf_config.h"
32 #include "yaf_loader.h"
33 #include "yaf_request.h"
34 #include "yaf_bootstrap.h"
35 #include "yaf_exception.h"
36 
37 zend_class_entry    *yaf_application_ce;
38 static zend_object_handlers yaf_application_obj_handlers;
39 
40 /** {{{ ARG_INFO
41  *  */
42 ZEND_BEGIN_ARG_INFO_EX(yaf_application_void_arginfo, 0, 0, 0)
ZEND_END_ARG_INFO()43 ZEND_END_ARG_INFO()
44 
45 ZEND_BEGIN_ARG_INFO_EX(yaf_application_construct_arginfo, 0, 0, 1)
46 	ZEND_ARG_INFO(0, config)
47 	ZEND_ARG_INFO(0, environ)
48 ZEND_END_ARG_INFO()
49 
50 ZEND_BEGIN_ARG_INFO_EX(yaf_application_app_arginfo, 0, 0, 0)
51 ZEND_END_ARG_INFO()
52 
53 ZEND_BEGIN_ARG_INFO_EX(yaf_application_execute_arginfo, 0, 0, 2)
54 	ZEND_ARG_INFO(0, entry)
55 	ZEND_ARG_INFO(0, ...)
56 ZEND_END_ARG_INFO()
57 
58 ZEND_BEGIN_ARG_INFO_EX(yaf_application_getconfig_arginfo, 0, 0, 0)
59 ZEND_END_ARG_INFO()
60 
61 ZEND_BEGIN_ARG_INFO_EX(yaf_application_getmodule_arginfo, 0, 0, 0)
62 ZEND_END_ARG_INFO()
63 
64 ZEND_BEGIN_ARG_INFO_EX(yaf_application_getdispatch_arginfo, 0, 0, 0)
65 ZEND_END_ARG_INFO()
66 
67 ZEND_BEGIN_ARG_INFO_EX(yaf_application_bootstrap_arginfo, 0, 0, 0)
68 	ZEND_ARG_INFO(0, bootstrap)
69 ZEND_END_ARG_INFO()
70 
71 ZEND_BEGIN_ARG_INFO_EX(yaf_application_environ_arginfo, 0, 0, 0)
72 ZEND_END_ARG_INFO()
73 
74 ZEND_BEGIN_ARG_INFO_EX(yaf_application_run_arginfo, 0, 0, 0)
75 ZEND_END_ARG_INFO()
76 
77 ZEND_BEGIN_ARG_INFO_EX(yaf_application_setappdir_arginfo, 0, 0, 1)
78 	ZEND_ARG_INFO(0, directory)
79 ZEND_END_ARG_INFO()
80 /* }}} */
81 
82 static void yaf_application_free(zend_object *object) /* {{{ */ {
83 	yaf_application_object *app = yaf_application_instance();
84 
85 	if ((app != php_yaf_application_fetch_object(object)) || !app->env) {
86 		zend_object_std_dtor(object);
87 		return;
88 	}
89 
90 	zend_string_release(app->env);
91 
92 	OBJ_RELEASE(Z_OBJ(app->config));
93 	OBJ_RELEASE(Z_OBJ(app->dispatcher));
94 
95 	zend_string_release(app->default_module);
96 	zend_string_release(app->default_controller);
97 	zend_string_release(app->default_action);
98 	if (app->library) {
99 		zend_string_release(app->library);
100 	}
101 	zend_string_release(app->directory);
102 
103 	if (app->ext) {
104 		zend_string_release(app->ext);
105 	}
106 	if (app->bootstrap) {
107 		zend_string_release(app->bootstrap);
108 	}
109 	if (app->view_ext) {
110 		zend_string_release(app->view_ext);
111 	}
112 	if (app->base_uri) {
113 		zend_string_release(app->base_uri);
114 	}
115 	if (app->err_msg) {
116 		zend_string_release(app->err_msg);
117 	}
118 	if (app->modules) {
119 		if (GC_DELREF(app->modules) == 0) {
120 			GC_REMOVE_FROM_BUFFER(app->modules);
121 			zend_array_destroy(app->modules);
122 		}
123 	}
124 	if (app->properties) {
125 		if (GC_DELREF(app->properties) == 0) {
126 			GC_REMOVE_FROM_BUFFER(app->properties);
127 			zend_array_destroy(app->properties);
128 		}
129 	}
130 
131 	zend_object_std_dtor(object);
132 }
133 /* }}} */
134 
yaf_application_new(zend_class_entry * ce)135 static zend_object* yaf_application_new(zend_class_entry *ce) /* {{{ */ {
136 	yaf_application_object *app = emalloc(sizeof(yaf_application_object) + zend_object_properties_size(ce));
137 
138 	memset(app, 0, XtOffsetOf(yaf_application_object, std));
139 	zend_object_std_init(&app->std, ce);
140 	app->std.handlers = &yaf_application_obj_handlers;
141 
142 	return &app->std;
143 }
144 /* }}} */
145 
yaf_application_get_gc(yaf_object * obj,zval ** table,int * n)146 static HashTable *yaf_application_get_gc(yaf_object *obj, zval **table, int *n) /* {{{ */ {
147 	yaf_application_object *app = php_yaf_application_fetch_object(yaf_strip_obj(obj));
148 
149 	*table = &app->dispatcher;
150 	*n = 2;
151 
152 	return NULL;
153 }
154 /* }}} */
155 
yaf_application_get_properties(yaf_object * obj)156 static HashTable *yaf_application_get_properties(yaf_object *obj) /* {{{ */ {
157 	zval rv;
158 	HashTable *ht;
159 	yaf_application_object *app = php_yaf_application_fetch_object(yaf_strip_obj(obj));
160 
161     if (!app->properties) {
162 		ALLOC_HASHTABLE(app->properties);
163 		zend_hash_init(app->properties, 16, NULL, ZVAL_PTR_DTOR, 0);
164 		YAF_ALLOW_VIOLATION(app->properties);
165 	}
166 
167 	ht = app->properties;
168 	ZVAL_STR_COPY(&rv, app->directory);
169 	zend_hash_str_update(ht, "directory", sizeof("directory") - 1, &rv);
170 
171 	if (app->library) {
172 		ZVAL_STR_COPY(&rv, app->library);
173 	} else {
174 		ZVAL_NULL(&rv);
175 	}
176 	zend_hash_str_update(ht, "library", sizeof("library") - 1, &rv);
177 
178 	if (app->bootstrap) {
179 		ZVAL_STR_COPY(&rv, app->bootstrap);
180 	} else {
181 		ZVAL_NULL(&rv);
182 	}
183 	zend_hash_str_update(ht, "bootstrap", sizeof("bootstrap") - 1, &rv);
184 
185 	if (app->ext) {
186 		ZVAL_STR_COPY(&rv, app->ext);
187 	} else {
188 		ZVAL_STRINGL(&rv, YAF_DEFAULT_EXT, sizeof(YAF_DEFAULT_EXT) - 1);
189 	}
190 	zend_hash_str_update(ht, "ext", sizeof("ext") - 1, &rv);
191 
192 	if (app->view_ext) {
193 		ZVAL_STR_COPY(&rv, app->view_ext);
194 	} else {
195 		ZVAL_STRINGL(&rv, YAF_DEFAULT_VIEW_EXT, sizeof(YAF_DEFAULT_VIEW_EXT) - 1);
196 	}
197 	zend_hash_str_update(ht, "view_ext", sizeof("view_ext") - 1, &rv);
198 
199 	ZVAL_STR_COPY(&rv, app->env);
200 	zend_hash_str_update(ht, "environ:protected", sizeof("environ:protected") - 1, &rv);
201 
202 	ZVAL_BOOL(&rv, YAF_APP_FLAGS(app) & YAF_APP_RUNNING);
203 	zend_hash_str_update(ht, "running:protected", sizeof("running:protected") - 1, &rv);
204 
205 	if (app->err_msg) {
206 		ZVAL_STR_COPY(&rv, app->err_msg);
207 	} else {
208 		ZVAL_NULL(&rv);
209 	}
210 	zend_hash_str_update(ht, "err_msg:protected", sizeof("err_msg:protected") - 1, &rv);
211 
212 	ZVAL_LONG(&rv, app->err_no);
213 	zend_hash_str_update(ht, "err_no:protected", sizeof("err_no:protected") - 1, &rv);
214 	if (Z_TYPE(app->config) == IS_OBJECT) {
215 		ZVAL_OBJ(&rv, Z_OBJ(app->config));
216 		Z_ADDREF(rv);
217 	} else {
218 		ZVAL_NULL(&rv);
219 	}
220 	zend_hash_str_update(ht, "config:protected", sizeof("config:protected") - 1, &rv);
221 
222 	if (Z_TYPE(app->dispatcher) == IS_OBJECT) {
223 		ZVAL_OBJ(&rv, Z_OBJ(app->dispatcher));
224 		GC_ADDREF(Z_OBJ(app->dispatcher));
225 	} else {
226 		ZVAL_NULL(&rv);
227 	}
228 	zend_hash_str_update(ht, "dispatcher:protected", sizeof("dispatcher:protected") - 1, &rv);
229 
230 	if (app->modules) {
231 		ZVAL_ARR(&rv, app->modules);
232 		GC_ADDREF(app->modules);
233 	} else {
234 		zval t;
235 		array_init(&rv);
236 		if (app->default_module) {
237 			ZVAL_STR_COPY(&t, app->default_module);
238 		} else {
239 			ZVAL_STR(&t, YAF_KNOWN_STR(YAF_DEFAULT_MODULE));
240 		}
241 		zend_hash_index_update(Z_ARRVAL(rv), 0, &t);
242 	}
243 	zend_hash_str_update(ht, "modules:protected", sizeof("modules:protected") - 1, &rv);
244 
245 	if (app->default_route) {
246 		ZVAL_ARR(&rv, zend_array_dup(app->default_route));
247 	} else {
248 		ZVAL_NULL(&rv);
249 	}
250 	zend_hash_str_update(ht, "default_route:protected", sizeof("default_route:protected") - 1, &rv);
251 
252 	return ht;
253 }
254 /* }}} */
255 
yaf_application_errors_hub(int type,...)256 static ZEND_COLD zend_never_inline void yaf_application_errors_hub(int type, ...) /* {{{ */ {
257 	va_list args;
258 
259 	va_start(args, type);
260 	if (type == 0) {
261 		yaf_application_object *app = va_arg(args, yaf_application_object*);
262 		if (Z_TYPE(YAF_G(app)) == IS_OBJECT) {
263 			zend_throw_exception_ex(NULL, YAF_ERR_STARTUP_FAILED, "Only one application can be initialized");
264 		} else if (Z_TYPE(app->config) != IS_OBJECT) {
265 			zend_throw_exception_ex(NULL, YAF_ERR_STARTUP_FAILED, "Initialization of application config failed");
266 		} else {
267 			zval *pzval;
268 			HashTable *conf = Z_YAFCONFIGOBJ(app->config)->config;
269 			if ((((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF_APPLICATION))) == NULL) || Z_TYPE_P(pzval) != IS_ARRAY) &&
270 					(((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF))) == NULL) || Z_TYPE_P(pzval) != IS_ARRAY)) {
271 				yaf_trigger_error(YAF_ERR_TYPE_ERROR, "%s", "Expected an array of application configuration");
272 			} else {
273 				yaf_trigger_error(YAF_ERR_STARTUP_FAILED, "%s", "Expected 'directory' entry in application configuration");
274 			}
275 			zval_ptr_dtor(&app->config);
276 		}
277 	} else if (type == 1) {
278 		zend_class_entry *ce = va_arg(args, zend_class_entry*);
279 		char *bootstrap_path = va_arg(args, char*);
280 
281 		if (ce) {
282 			yaf_trigger_error(YAF_ERR_TYPE_ERROR, "'%s' is not a subclass of %s", ZSTR_VAL(ce->name), ZSTR_VAL(yaf_bootstrap_ce->name));
283 		} else if (zend_hash_str_exists(&EG(included_files), bootstrap_path, strlen(bootstrap_path))) {
284 			php_error_docref(NULL, E_WARNING, "Couldn't find class %s in %s", YAF_DEFAULT_BOOTSTRAP, bootstrap_path);
285 		} else {
286 			php_error_docref(NULL, E_WARNING, "Couldn't find bootstrap file %s", bootstrap_path);
287 		}
288 	}
289 	va_end(args);
290 }
291 /* }}} */
292 
yaf_application_get_dispatcher(yaf_application_object * app)293 static inline zend_object *yaf_application_get_dispatcher(yaf_application_object *app) /* {{{ */ {
294 	if (Z_TYPE(app->dispatcher) == IS_OBJECT) {
295 		Z_ADDREF(app->dispatcher);
296 		return Z_OBJ(app->dispatcher);
297 	}
298 	return NULL;
299 }
300 /* }}} */
301 
yaf_application_get_config(yaf_application_object * app)302 static inline zend_object *yaf_application_get_config(yaf_application_object *app) /* {{{ */ {
303 	if (Z_TYPE(app->config) == IS_OBJECT) {
304 		GC_ADDREF(Z_OBJ(app->config));
305 		return Z_OBJ(app->config);
306 	}
307 	return NULL;
308 }
309 /* }}} */
310 
yaf_application_read_property(yaf_object * obj,void * name,int type,void ** cache_slot,zval * rv)311 static zval *yaf_application_read_property(yaf_object *obj, void *name, int type, void **cache_slot, zval *rv) /* {{{ */ {
312 	zend_string *member;
313 	yaf_application_object *app = php_yaf_application_fetch_object(yaf_strip_obj(obj));
314 
315 #if PHP_VERSION_ID < 80000
316 	if (UNEXPECTED(Z_TYPE_P((zval*)name) != IS_STRING)) {
317 		return &EG(uninitialized_zval);
318 	}
319     member = Z_STR_P((zval*)name);
320 #else
321 	member = (zend_string*)name;
322 #endif
323 
324 	if (UNEXPECTED(type == BP_VAR_W || type == BP_VAR_RW)) {
325 		return &EG(error_zval);
326 	}
327 
328 	if (zend_string_equals_literal(member, "directory")) {
329 		if (app->directory) {
330 			ZVAL_STR_COPY(rv, app->directory);
331 			return rv;
332 		}
333 		return &EG(uninitialized_zval);
334 	}
335 
336 	if (zend_string_equals_literal(member, "library")) {
337 		if (app->library) {
338 			ZVAL_STR_COPY(rv, app->library);
339 			return rv;
340 		}
341 		return &EG(uninitialized_zval);
342 	}
343 
344 	if (zend_string_equals_literal(member, "bootstrap")) {
345 		if (app->bootstrap) {
346 			ZVAL_STR_COPY(rv, app->bootstrap);
347 			return rv;
348 		}
349 		return &EG(uninitialized_zval);
350 	}
351 
352 	if (zend_string_equals_literal(member, "ext")) {
353 		if (app->ext) {
354 			ZVAL_STR_COPY(rv, app->ext);
355 			return rv;
356 		}
357 		return &EG(uninitialized_zval);
358 	}
359 
360 	if (zend_string_equals_literal(member, "view_ext")) {
361 		if (app->view_ext) {
362 			ZVAL_STR_COPY(rv, app->view_ext);
363 			return rv;
364 		}
365 		return &EG(uninitialized_zval);
366 	}
367 
368 	/*
369 	if (zend_string_equals_literal(member, "environ")) {
370 		if (app->env) {
371 			ZVAL_STR_COPY(rv, app->env);
372 			return rv;
373 		}
374 		return &EG(uninitialized_zval);
375 	}
376 
377 	if (zend_string_equals_literal(member, "running")) {
378 		ZVAL_BOOL(rv, app->running);
379 		return rv;
380 	}
381 
382 
383 	if (zend_string_equals_literal(member, "dispatcher")) {
384 		zend_object *dispatcher = yaf_application_get_dispatcher(app);
385 		if (dispatcher) {
386 			ZVAL_OBJ(rv, dispatcher);
387 			return rv;
388 		}
389 		return &EG(uninitialized_zval);
390 	}
391 
392 	if (zend_string_equals_literal(member, "config")) {
393 		zend_object *config = yaf_application_get_config(app);
394 		if (config) {
395 			ZVAL_OBJ(rv, config);
396 			return rv;
397 		}
398 		return &EG(uninitialized_zval);
399 	}
400 
401 	if (zend_string_equals_literal(member, "err_msg")) {
402 		if (app->err_msg) {
403 			ZVAL_STR_COPY(rv, app->err_msg);
404 			return rv;
405 		}
406 		return &EG(uninitialized_zval);
407 	}
408 
409 	if (zend_string_equals_literal(member, "err_no")) {
410 		ZVAL_BOOL(rv, app->err_no);
411 		return rv;
412 	}
413 	*/
414 
415 	return &EG(uninitialized_zval);
416 }
417 /* }}} */
418 
yaf_application_write_property(yaf_object * obj,void * name,zval * value,void ** cache_slot)419 static YAF_WRITE_HANDLER yaf_application_write_property(yaf_object *obj, void *name, zval *value, void **cache_slot) /* {{{ */ {
420 	zend_string *member;
421 	yaf_application_object *app = php_yaf_application_fetch_object(yaf_strip_obj(obj));
422 
423 #if PHP_VERSION_ID < 80000
424 	if (UNEXPECTED(Z_TYPE_P((zval*)name) != IS_STRING)) {
425 		YAF_WHANDLER_RET(value);
426 	}
427     member = Z_STR_P((zval*)name);
428 #else
429 	member = (zend_string*)name;
430 #endif
431 
432 	if (zend_string_equals_literal(member, "directory")) {
433 		if (Z_TYPE_P(value) != IS_STRING) {
434 			YAF_WHANDLER_RET(value);
435 		}
436 		if (app->directory) {
437 			zend_string_release(app->directory);
438 		}
439 		app->directory = zend_string_copy(Z_STR_P(value));
440 		YAF_WHANDLER_RET(value);
441 	}
442 
443 	if (zend_string_equals_literal(member, "bootstrap")) {
444 		if (Z_TYPE_P(value) != IS_STRING) {
445 			YAF_WHANDLER_RET(value);
446 		}
447 		if (app->bootstrap) {
448 			zend_string_release(app->bootstrap);
449 		}
450 		app->bootstrap = zend_string_copy(Z_STR_P(value));
451 		YAF_WHANDLER_RET(value);
452 	}
453 
454 	if (zend_string_equals_literal(member, "library")) {
455 		if (Z_TYPE_P(value) != IS_STRING) {
456 			YAF_WHANDLER_RET(value);
457 		}
458 		if (app->library) {
459 			zend_string_release(app->library);
460 		}
461 		app->library = zend_string_copy(Z_STR_P(value));
462 		YAF_WHANDLER_RET(value);
463 	}
464 
465 	if (zend_string_equals_literal(member, "view_ext")) {
466 		if (Z_TYPE_P(value) != IS_STRING) {
467 			YAF_WHANDLER_RET(value);
468 		}
469 		if (app->view_ext) {
470 			zend_string_release(app->view_ext);
471 		}
472 		app->view_ext = zend_string_copy(Z_STR_P(value));
473 		YAF_WHANDLER_RET(value);
474 	}
475 
476 	if (zend_string_equals_literal(member, "ext")) {
477 		if (Z_TYPE_P(value) != IS_STRING) {
478 			YAF_WHANDLER_RET(value);
479 		}
480 		if (app->ext) {
481 			zend_string_release(app->ext);
482 		}
483 		app->ext = zend_string_copy(Z_STR_P(value));
484 		YAF_WHANDLER_RET(value);
485 	}
486 
487 	YAF_WHANDLER_RET(value);
488 }
489 /* }}} */
490 
yaf_application_is_module_name(zend_string * name)491 ZEND_HOT int yaf_application_is_module_name(zend_string *name) /* {{{ */ {
492 	zval *pzval;
493 	yaf_application_object *app = yaf_application_instance();
494 
495 	if (UNEXPECTED(app == NULL)) {
496 		return 0;
497 	}
498 	if (app->modules == NULL) {
499 		if (UNEXPECTED(app->default_module)) {
500 			return zend_string_equals_ci(app->default_module, name);
501 		}
502 		return zend_string_equals_ci(name, YAF_KNOWN_STR(YAF_DEFAULT_MODULE));
503 	}
504 
505 	ZEND_HASH_FOREACH_VAL(app->modules, pzval) {
506 		if (UNEXPECTED(Z_TYPE_P(pzval) != IS_STRING)) {
507 			continue;
508 		}
509 		if (zend_string_equals_ci(Z_STR_P(pzval), name)) {
510 			return 1;
511 		}
512 	} ZEND_HASH_FOREACH_END();
513 	return 0;
514 }
515 /* }}} */
516 
yaf_application_is_module_name_str(const char * name,size_t len)517 ZEND_HOT int yaf_application_is_module_name_str(const char *name, size_t len) /* {{{ */ {
518 	zval *pzval;
519 	yaf_application_object *app = yaf_application_instance();
520 
521 	if (UNEXPECTED(app == NULL)) {
522 		return 0;
523 	}
524 	if (app->modules == NULL) {
525 		if (UNEXPECTED(app->default_module)) {
526 			return len == ZSTR_LEN(app->default_module) && !strncasecmp(name, ZSTR_VAL(app->default_module), len);
527 		}
528 		return len == strlen(YAF_KNOWN_CHARS(YAF_DEFAULT_MODULE)) &&
529 			!strncasecmp(name, YAF_KNOWN_CHARS(YAF_DEFAULT_MODULE), len);
530 	}
531 
532 	ZEND_HASH_FOREACH_VAL(app->modules, pzval) {
533 		if (UNEXPECTED(Z_TYPE_P(pzval) != IS_STRING)) {
534 			continue;
535 		}
536 		if (Z_STRLEN_P(pzval) == len && strncasecmp(Z_STRVAL_P(pzval), name, len) == 0) {
537 			return 1;
538 		}
539 	} ZEND_HASH_FOREACH_END();
540 
541 	return 0;
542 }
543 /* }}} */
544 
yaf_application_parse_optional(yaf_application_object * app,zend_array * conf)545 static zend_never_inline void yaf_application_parse_optional(yaf_application_object *app, zend_array *conf) /* {{{ */ {
546 	zval *pzval, *psval;
547 
548 	/* following options are optional */
549 	if (UNEXPECTED((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF_BOOTSTRAP))) != NULL &&
550 		Z_TYPE_P(pzval) == IS_STRING)) {
551 		app->bootstrap = zend_string_copy(Z_STR_P(pzval));
552 	}
553 
554 	if (UNEXPECTED((pzval = zend_hash_str_find(conf, ZEND_STRL("ext"))) != NULL &&
555 		Z_TYPE_P(pzval) == IS_STRING)) {
556 		app->ext = zend_string_copy(Z_STR_P(pzval));
557 	}
558 
559 	if (UNEXPECTED((pzval = zend_hash_str_find(conf, ZEND_STRL("library"))) != NULL)) {
560 		if (EXPECTED(IS_STRING == Z_TYPE_P(pzval))) {
561 			app->library = zend_string_copy(Z_STR_P(pzval));
562 		} else if (IS_ARRAY == Z_TYPE_P(pzval)) {
563 			if ((psval = zend_hash_find(Z_ARRVAL_P(pzval), YAF_KNOWN_STR(YAF_DIRECTORY))) != NULL &&
564 				Z_TYPE_P(psval) == IS_STRING) {
565 				app->library = zend_string_copy(Z_STR_P(psval));
566 			}
567 			if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("namespace"))) != NULL) {
568 				yaf_loader_object *loader = Z_YAFLOADEROBJ(YAF_G(loader));
569 				if (Z_TYPE_P(psval) == IS_STRING) {
570 					if (Z_STRLEN_P(psval)) {
571 						zend_string *prefix;
572 						char *src = Z_STRVAL_P(psval), *pos;
573 						size_t len = Z_STRLEN_P(psval);
574 						while ((pos = memchr(src, ',', len))) {
575 							len -= (pos - src) + 1;
576 							while (*src == ' ') src++;
577 							prefix = zend_string_init(src, pos - src, 0);
578 							yaf_loader_register_namespace(loader, prefix, NULL);
579 							zend_string_release(prefix);
580 							src = pos + 1;
581 						}
582 
583 						if (len) {
584 							while (*src == ' ') src++, len--;
585 							prefix = zend_string_init(src, len, 0);
586 							yaf_loader_register_namespace(loader, prefix, NULL);
587 							zend_string_release(prefix);
588 						}
589 					}
590 				} else if (Z_TYPE_P(psval) == IS_ARRAY) {
591 					zend_string *name;
592 					zval *path;
593 					ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(psval), name, path) {
594 						if (name == NULL) {
595 							continue;
596 						}
597 						if (Z_TYPE_P(path) == IS_STRING) {
598 							yaf_loader_register_namespace(Z_YAFLOADEROBJ(YAF_G(loader)), name, Z_STR_P(path));
599 						} else {
600 							yaf_loader_register_namespace(Z_YAFLOADEROBJ(YAF_G(loader)), name, NULL);
601 						}
602 					} ZEND_HASH_FOREACH_END();
603 				}
604 			}
605 		}
606 	}
607 
608 	if (UNEXPECTED((pzval = zend_hash_str_find(conf, ZEND_STRL("view"))) != NULL &&
609 		Z_TYPE_P(pzval) == IS_ARRAY &&
610 		((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("ext"))) != NULL &&
611 		 Z_TYPE_P(psval) == IS_STRING))) {
612 		app->view_ext = zend_string_copy(Z_STR_P(psval));
613 	}
614 
615 	if (UNEXPECTED((pzval = zend_hash_str_find(conf, ZEND_STRL("baseUri"))) != NULL &&
616 		Z_TYPE_P(pzval) == IS_STRING)) {
617 		app->base_uri = zend_string_copy(Z_STR_P(pzval));
618 	}
619 
620 	do {
621 		zval rv;
622 		if (UNEXPECTED((pzval = zend_hash_str_find(conf, ZEND_STRL("modules"))) != NULL &&
623 			Z_TYPE_P(pzval) == IS_STRING && Z_STRLEN_P(pzval))) {
624 			char *ptrptr = NULL;
625 			char *seg, *modules;
626 
627 			ALLOC_HASHTABLE(app->modules);
628 			zend_hash_init(app->modules, 8, NULL, ZVAL_PTR_DTOR, 0);
629 			YAF_ALLOW_VIOLATION(app->modules);
630 
631 			modules = estrndup(Z_STRVAL_P(pzval), Z_STRLEN_P(pzval));
632 			seg = php_strtok_r(modules, ",", &ptrptr);
633 			while (seg) {
634 				if (seg && strlen(seg)) {
635 					ZVAL_STR(&rv, yaf_build_camel_name(seg, strlen(seg)));
636 					zend_hash_next_index_insert(app->modules, &rv);
637 				}
638 				seg = php_strtok_r(NULL, ",", &ptrptr);
639 			}
640 			efree(modules);
641 		}
642 	} while (0);
643 
644 	if (UNEXPECTED((pzval = zend_hash_str_find(conf, ZEND_STRL("system"))) != NULL &&
645 		Z_TYPE_P(pzval) == IS_ARRAY)) {
646 		zval *value;
647 		char name[128];
648 		zend_string *key;
649 		size_t len;
650 
651 		ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pzval), key, value) {
652 			zend_string *str, *val;
653 			len = snprintf(name, sizeof(name), "%s.%s", "yaf", ZSTR_VAL(key));
654 			if (len > sizeof(name) -1) {
655 				continue;
656 			}
657 			str = zend_string_init(name, len, 0);
658 			val = zval_get_string(value);
659 			zend_alter_ini_entry(str, val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
660 			zend_string_release(str);
661 			zend_string_release(val);
662 		} ZEND_HASH_FOREACH_END();
663 
664 		/* We have to reset the loader as the yaf.* inis has beend changed */
665 		yaf_loader_reset(Z_YAFLOADEROBJ(YAF_G(loader)));
666 		if (*YAF_G(global_library)) {
667 			zend_string *library = zend_string_init(YAF_G(global_library), strlen(YAF_G(global_library)), 0);
668 			yaf_loader_set_global_library_path(Z_YAFLOADEROBJ(YAF_G(loader)), library);
669 			zend_string_release(library);
670 		}
671 	}
672 }
673 /* }}} */
674 
yaf_application_parse_option(yaf_application_object * app)675 int yaf_application_parse_option(yaf_application_object *app) /* {{{ */ {
676 	zval *pzval;
677 	HashTable *conf;
678 	uint32_t items;
679 
680 	conf = Z_YAFCONFIGOBJ(app->config)->config;
681 	if (UNEXPECTED((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF_APPLICATION))) == NULL) || Z_TYPE_P(pzval) != IS_ARRAY) {
682 		/* For back compatibilty */
683 		if (((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF))) == NULL) || Z_TYPE_P(pzval) != IS_ARRAY) {
684 			return 0;
685 		}
686 	}
687 
688 	conf = Z_ARRVAL_P(pzval);
689 	if (UNEXPECTED((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF_DIRECTORY))) == NULL ||
690 		Z_TYPE_P(pzval) != IS_STRING || Z_STRLEN_P(pzval) == 0)) {
691 		return 0;
692 	}
693 
694 	if (UNEXPECTED(*(Z_STRVAL_P(pzval) + Z_STRLEN_P(pzval) - 1) == DEFAULT_SLASH)) {
695 		app->directory = zend_string_init(Z_STRVAL_P(pzval), Z_STRLEN_P(pzval) - 1, 0);
696 	} else {
697 		app->directory = zend_string_copy(Z_STR_P(pzval));
698 	}
699 
700 	items = zend_hash_num_elements(conf) - 1;
701 	if (UNEXPECTED((pzval = zend_hash_find(conf, YAF_KNOWN_STR(YAF_DISPATCHER))) != NULL &&
702 		Z_TYPE_P(pzval) == IS_ARRAY)) {
703 		zval *psval;
704 
705 		items--;
706 		if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("defaultModule"))) != NULL &&
707 			Z_TYPE_P(psval) == IS_STRING) {
708 			app->default_module = yaf_canonical_name(1, Z_STR_P(psval));
709 		} else {
710 			app->default_module = YAF_KNOWN_STR(YAF_DEFAULT_MODULE);
711 		}
712 
713 		if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("defaultController"))) != NULL &&
714 			Z_TYPE_P(psval) == IS_STRING) {
715 			app->default_controller = yaf_canonical_name(1, Z_STR_P(psval));
716 		} else {
717 			app->default_controller = YAF_KNOWN_STR(YAF_DEFAULT_CONTROLLER);
718 		}
719 
720 		if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("defaultAction"))) != NULL &&
721 			Z_TYPE_P(psval) == IS_STRING) {
722 			app->default_action = yaf_canonical_name(0, Z_STR_P(psval));
723 		} else {
724 			app->default_action = YAF_KNOWN_STR(YAF_DEFAULT_ACTION);
725 		}
726 
727 		if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("throwException"))) != NULL) {
728 			yaf_set_throw_exception(zend_is_true(psval));
729 		}
730 
731 		if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("catchException"))) != NULL) {
732 			yaf_set_catch_exception(zend_is_true(psval));
733 		}
734 
735 		if ((psval = zend_hash_str_find(Z_ARRVAL_P(pzval), ZEND_STRL("defaultRoute"))) != NULL &&
736 			Z_TYPE_P(psval) == IS_ARRAY) {
737 			/* leave it to configs destructor */
738 			app->default_route = Z_ARRVAL_P(psval);
739 		}
740 	} else {
741 		app->default_module = YAF_KNOWN_STR(YAF_DEFAULT_MODULE);
742 		app->default_controller = YAF_KNOWN_STR(YAF_DEFAULT_CONTROLLER);
743 		app->default_action = YAF_KNOWN_STR(YAF_DEFAULT_ACTION);
744 	}
745 
746 	/* prasing optional configs */
747 	if (items) {
748 		yaf_application_parse_optional(app, conf);
749 	}
750 
751 	return 1;
752 }
753 /* }}} */
754 
755 /** {{{ proto Yaf_Application::__construct(mixed $config, string $environ = YAF_G(environ_name))
756 */
PHP_METHOD(yaf_application,__construct)757 PHP_METHOD(yaf_application, __construct) {
758 	zval *config;
759 	zend_string *section = NULL;
760 	yaf_loader_t *loader;
761 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
762 
763 	if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "z|S", &config, &section) == FAILURE) {
764 		return;
765 	}
766 
767 	if (EXPECTED(Z_TYPE(YAF_G(app)) != IS_OBJECT)) {
768 		if (!section || !ZSTR_LEN(section)) {
769 			section = zend_string_init(YAF_G(environ_name), strlen(YAF_G(environ_name)), 0);
770 		} else {
771 			zend_string_copy(section);
772 		}
773 		yaf_config_instance(&app->config, config, section);
774 		if (EXPECTED(Z_TYPE(app->config) == IS_OBJECT)) {
775 			loader = yaf_loader_instance(NULL);
776 			if (EXPECTED(yaf_application_parse_option(app))) {
777 				app->env = section /* initialized flag */;
778 				if (app->library == NULL) {
779 					zend_string *local_library = zend_string_alloc(ZSTR_LEN(app->directory) + sizeof(YAF_LIBRARY_DIRECTORY_NAME), 0);
780 					yaf_compose_2_pathes(ZSTR_VAL(local_library), app->directory, ZEND_STRS(YAF_LIBRARY_DIRECTORY_NAME));
781 					yaf_loader_set_library_path_ex(Z_YAFLOADEROBJ_P(loader), local_library);
782 				} else {
783 					yaf_loader_set_library_path(Z_YAFLOADEROBJ_P(loader), app->library);
784 				}
785 
786 				GC_ADDREF(&app->std);
787 				ZVAL_OBJ(&YAF_G(app), &app->std);
788 				yaf_dispatcher_instance(&app->dispatcher);
789 				yaf_request_instance(&Z_YAFDISPATCHEROBJ(app->dispatcher)->request, app->base_uri);
790 				return;
791 			}
792 		}
793 		zend_string_release(section);
794 	}
795 
796 	yaf_application_errors_hub(0, app);
797 	return;
798 }
799 /* }}} */
800 
801 /** {{{ proto public Yaf_Application::run(void)
802 */
PHP_METHOD(yaf_application,run)803 PHP_METHOD(yaf_application, run) {
804 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
805 	yaf_response_t *response;
806 
807 	if (UNEXPECTED(YAF_APP_FLAGS(app) & YAF_APP_RUNNING)) {
808 		yaf_trigger_error(YAF_ERR_STARTUP_FAILED, "Application is already started");
809 		RETURN_FALSE;
810 	}
811 
812 	YAF_APP_FLAGS(app) |= YAF_APP_RUNNING;
813 	if ((response = yaf_dispatcher_dispatch(Z_YAFDISPATCHEROBJ(app->dispatcher)))) {
814 		YAF_APP_FLAGS(app) &= ~YAF_APP_RUNNING;
815 		RETURN_ZVAL(response, 1, 0);
816 	}
817 
818 	YAF_APP_FLAGS(app) &= ~YAF_APP_RUNNING;
819 	RETURN_FALSE;
820 }
821 /* }}} */
822 
823 /** {{{ proto public Yaf_Application::bootstrap(void)
824 */
PHP_METHOD(yaf_application,bootstrap)825 PHP_METHOD(yaf_application, bootstrap) {
826 	zval bootstrap;
827 	zend_string *func;
828 	char buf[MAXPATHLEN];
829 	zend_function *fptr;
830 	zend_class_entry  *ce;
831 	const char *bootstrap_path;
832 	uint32_t bootstrap_path_len;
833 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
834 	yaf_dispatcher_t *dispatcher = &app->dispatcher;
835 
836 	if (!(ce = zend_hash_find_ptr(EG(class_table), YAF_KNOWN_STR(YAF_BOOTSTRAP)))) {
837 		if (UNEXPECTED(app->bootstrap)) {
838 			bootstrap_path = ZSTR_VAL(app->bootstrap);
839 			bootstrap_path_len = ZSTR_LEN(app->bootstrap);
840 		} else {
841 			bootstrap_path_len = yaf_compose_2_pathes(buf, app->directory, ZEND_STRL(YAF_DEFAULT_BOOTSTRAP));
842 			buf[bootstrap_path_len++] = '.';
843 			if (UNEXPECTED(app->ext)) {
844 				memcpy(buf + bootstrap_path_len, ZSTR_VAL(app->ext), ZSTR_LEN(app->ext));
845 				bootstrap_path_len += ZSTR_LEN(app->ext);
846 			} else {
847 				memcpy(buf + bootstrap_path_len, YAF_DEFAULT_EXT, sizeof(YAF_DEFAULT_EXT) - 1);
848 				bootstrap_path_len += sizeof(YAF_DEFAULT_EXT) - 1;
849 			}
850 			buf[bootstrap_path_len] = '\0';
851 			bootstrap_path = buf;
852 		}
853 		if (UNEXPECTED((!yaf_loader_import(bootstrap_path, bootstrap_path_len)) ||
854 			(!(ce = zend_hash_find_ptr(EG(class_table), YAF_KNOWN_STR(YAF_BOOTSTRAP)))))) {
855 			goto error;
856 		}
857 	}
858 
859 	if (EXPECTED(instanceof_function(ce, yaf_bootstrap_ce))) {
860 		zend_object *obj;
861 
862 		object_init_ex(&bootstrap, ce);
863 		obj = Z_OBJ(bootstrap);
864 		ZEND_HASH_FOREACH_STR_KEY_PTR(&(ce->function_table), func, fptr) {
865 			zval ret;
866 			if (UNEXPECTED(ZSTR_LEN(func) < sizeof("_init")) ||
867 				!yaf_slip_equal(ZSTR_VAL(func), ZEND_STRL(YAF_BOOTSTRAP_INITFUNC_PREFIX))) {
868 				continue;
869 			}
870 			if (UNEXPECTED(!yaf_call_user_method_with_1_arguments(obj, fptr, dispatcher, &ret))) {
871 				/** an uncaught exception threw in function call */
872 				if (UNEXPECTED(EG(exception))) {
873 					OBJ_RELEASE(Z_OBJ(bootstrap));
874 					RETURN_FALSE;
875 				}
876 			}
877 			/* Must always return bool? */
878 			/* zval_ptr_dtor(&ret); */
879 		} ZEND_HASH_FOREACH_END();
880 		OBJ_RELEASE(Z_OBJ(bootstrap));
881 
882 		RETURN_ZVAL(getThis(), 1, 0);
883 	}
884 
885 error:
886 	yaf_application_errors_hub(1, ce, bootstrap_path);
887 	RETURN_FALSE;
888 }
889 /* }}} */
890 
891 /** {{{ proto public Yaf_Application::getDispatcher(void)
892 */
PHP_METHOD(yaf_application,getDispatcher)893 PHP_METHOD(yaf_application, getDispatcher) {
894 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
895 	zend_object *dispatcher = yaf_application_get_dispatcher(app);
896 
897 	if (dispatcher) {
898 		RETURN_OBJ(dispatcher);
899 	}
900 
901 	RETURN_NULL();
902 }
903 /* }}} */
904 
905 /** {{{ proto public Yaf_Application::getConfig(void)
906 */
PHP_METHOD(yaf_application,getConfig)907 PHP_METHOD(yaf_application, getConfig) {
908 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
909 	zend_object *config = yaf_application_get_config(app);
910 
911 	if (config) {
912 		RETURN_OBJ(config);
913 	}
914 
915 	RETURN_NULL();
916 }
917 /* }}} */
918 
919 /** {{{ proto public Yaf_Application::app(void)
920 */
PHP_METHOD(yaf_application,app)921 PHP_METHOD(yaf_application, app) {
922 	RETURN_ZVAL(&YAF_G(app), 1, 0);
923 }
924 /* }}} */
925 
926 /** {{{ proto public Yaf_Application::getModules(void)
927 */
PHP_METHOD(yaf_application,getModules)928 PHP_METHOD(yaf_application, getModules) {
929 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
930 
931 	if (app->modules) {
932 		GC_ADDREF(app->modules);
933 		RETURN_ARR(app->modules);
934 	} else {
935 		RETURN_NULL();
936 	}
937 }
938 /* }}} */
939 
940 /** {{{ proto public Yaf_Application::environ(void)
941 */
PHP_METHOD(yaf_application,environ)942 PHP_METHOD(yaf_application, environ) {
943 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
944 
945 	if (zend_parse_parameters_none() == FAILURE) {
946 		return;
947 	}
948 	if (app->env) {
949 		RETURN_STR(zend_string_copy(app->env));
950 	}
951 	RETURN_EMPTY_STRING();
952 }
953 /* }}} */
954 
955 /** {{{ proto public Yaf_Application::execute(callback $func)
956  * We can not call to zif_call_user_func on windows, since it was not declared with dllexport
957  */
PHP_METHOD(yaf_application,execute)958 PHP_METHOD(yaf_application, execute) {
959 	zval retval;
960 	zend_fcall_info fci;
961 	zend_fcall_info_cache fci_cache;
962 
963 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "f*", &fci, &fci_cache, &fci.params, &fci.param_count) == FAILURE) {
964 		return;
965 	}
966 
967 	fci.retval = &retval;
968 
969 	if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
970 		ZVAL_COPY_VALUE(return_value, &retval);
971 	} else {
972 		RETURN_FALSE;
973 	}
974 }
975 /* }}} */
976 
977 /** {{{ proto public Yaf_Application::getLastErrorNo(void)
978 */
PHP_METHOD(yaf_application,getLastErrorNo)979 PHP_METHOD(yaf_application, getLastErrorNo) {
980 	if (zend_parse_parameters_none() == FAILURE) {
981 		return;
982 	}
983 	RETURN_LONG(Z_YAFAPPOBJ_P(getThis())->err_no);
984 }
985 /* }}} */
986 
987 /** {{{ proto public Yaf_Application::getLastErrorMsg(void)
988 */
PHP_METHOD(yaf_application,getLastErrorMsg)989 PHP_METHOD(yaf_application, getLastErrorMsg) {
990 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
991 
992 	if (zend_parse_parameters_none() == FAILURE) {
993 		return;
994 	}
995 	if (app->err_msg) {
996 		RETURN_STR_COPY(app->err_msg);
997 	} else {
998 		RETURN_EMPTY_STRING();
999 	}
1000 }
1001 /* }}} */
1002 
1003 /** {{{ proto public Yaf_Application::clearLastError(void)
1004 */
PHP_METHOD(yaf_application,clearLastError)1005 PHP_METHOD(yaf_application, clearLastError) {
1006 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
1007 
1008 	if (zend_parse_parameters_none() == FAILURE) {
1009 		return;
1010 	}
1011 	if (app->err_msg) {
1012 		zend_string_release(app->err_msg);
1013 		app->err_msg = NULL;
1014 	}
1015 	app->err_no = 0;
1016 	RETURN_ZVAL(getThis(), 1, 0);
1017 }
1018 /* }}} */
1019 
1020 /** {{{ proto public Yaf_Application::setAppDirectory(string $directory)
1021 */
PHP_METHOD(yaf_application,setAppDirectory)1022 PHP_METHOD(yaf_application, setAppDirectory) {
1023 	zend_string *directory;
1024 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
1025 
1026 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &directory) == FAILURE) {
1027 		return;
1028 	}
1029 
1030 	if (ZSTR_LEN(directory) == 0 || !IS_ABSOLUTE_PATH(ZSTR_VAL(directory), ZSTR_LEN(directory))) {
1031 		RETURN_FALSE;
1032 	}
1033 
1034 	zend_string_release(app->directory);
1035 	app->directory = zend_string_copy(directory);
1036 
1037 	RETURN_ZVAL(getThis(), 1, 0);
1038 }
1039 /* }}} */
1040 
1041 /** {{{ proto public Yaf_Application::getAppDirectory(void)
1042 */
PHP_METHOD(yaf_application,getAppDirectory)1043 PHP_METHOD(yaf_application, getAppDirectory) {
1044 	yaf_application_object *app = Z_YAFAPPOBJ_P(getThis());
1045 
1046 	if (zend_parse_parameters_none() == FAILURE) {
1047 		return;
1048 	}
1049 
1050 	if (app->directory) {
1051 		RETURN_STR(zend_string_copy(app->directory));
1052 	} else {
1053 		RETURN_NULL();
1054 	}
1055 }
1056 /* }}} */
1057 
1058 /** {{{ yaf_application_methods
1059 */
1060 zend_function_entry yaf_application_methods[] = {
1061 	PHP_ME(yaf_application, __construct,         yaf_application_construct_arginfo,     ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
1062 	PHP_ME(yaf_application, run,                 yaf_application_run_arginfo,         ZEND_ACC_PUBLIC)
1063 	PHP_ME(yaf_application, execute,             yaf_application_execute_arginfo,     ZEND_ACC_PUBLIC)
1064 	PHP_ME(yaf_application, app,                 yaf_application_app_arginfo,         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
1065 	YAF_ME(yaf_application_environ, "environ",   yaf_application_environ_arginfo,     ZEND_ACC_PUBLIC)
1066 	PHP_ME(yaf_application, bootstrap,           yaf_application_bootstrap_arginfo,      ZEND_ACC_PUBLIC)
1067 	PHP_ME(yaf_application, getConfig,           yaf_application_getconfig_arginfo,     ZEND_ACC_PUBLIC)
1068 	PHP_ME(yaf_application, getModules,          yaf_application_getmodule_arginfo,      ZEND_ACC_PUBLIC)
1069 	PHP_ME(yaf_application, getDispatcher,       yaf_application_getdispatch_arginfo,    ZEND_ACC_PUBLIC)
1070 	PHP_ME(yaf_application, setAppDirectory,     yaf_application_setappdir_arginfo,      ZEND_ACC_PUBLIC)
1071 	PHP_ME(yaf_application, getAppDirectory,     yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
1072 	PHP_ME(yaf_application, getLastErrorNo,      yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
1073 	PHP_ME(yaf_application, getLastErrorMsg,     yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
1074 	PHP_ME(yaf_application, clearLastError,      yaf_application_void_arginfo,         ZEND_ACC_PUBLIC)
1075 	PHP_MALIAS(yaf_application, getInstance, app, yaf_application_app_arginfo, ZEND_ACC_PUBLIC)
1076 	{NULL, NULL, NULL}
1077 };
1078 /* }}} */
1079 
1080 /** {{{ YAF_STARTUP_FUNCTION
1081 */
YAF_STARTUP_FUNCTION(application)1082 YAF_STARTUP_FUNCTION(application) {
1083 	zend_class_entry ce;
1084 	YAF_INIT_CLASS_ENTRY(ce, "Yaf_Application", "Yaf\\Application", yaf_application_methods);
1085 
1086 	yaf_application_ce = zend_register_internal_class_ex(&ce, NULL);
1087 	yaf_application_ce->ce_flags |= ZEND_ACC_FINAL;
1088 	yaf_application_ce->create_object = yaf_application_new;
1089 	yaf_application_ce->serialize = zend_class_serialize_deny;
1090 	yaf_application_ce->unserialize = zend_class_unserialize_deny;
1091 
1092 	memcpy(&yaf_application_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1093 	yaf_application_obj_handlers.offset = XtOffsetOf(yaf_application_object, std);
1094 	yaf_application_obj_handlers.clone_obj = NULL;
1095 	yaf_application_obj_handlers.get_gc = yaf_application_get_gc;
1096 	yaf_application_obj_handlers.free_obj = yaf_application_free;
1097 	yaf_application_obj_handlers.get_properties = yaf_application_get_properties;
1098 	yaf_application_obj_handlers.read_property = (zend_object_read_property_t)yaf_application_read_property;
1099 	yaf_application_obj_handlers.write_property = (zend_object_write_property_t)yaf_application_write_property;
1100 
1101 	return SUCCESS;
1102 }
1103 /* }}} */
1104 
1105 /*
1106  * Local variables:
1107  * tab-width: 4
1108  * c-basic-offset: 4
1109  * End:
1110  * vim600: noet sw=4 ts=4 fdm=marker
1111  * vim<600: noet sw=4 ts=4
1112  */
1113