├── EXPERIMENTAL ├── fool_exception.h ├── config.w32 ├── fool_object.h ├── fool_application.h ├── fool_loader.h ├── fool_dispatcher.h ├── fool_config.h ├── fool_controller.h ├── foolphp.php ├── fool_view.h ├── tests └── 001.phpt ├── fool_request.h ├── config.h ├── config.m4 ├── fool_exception.c ├── tools ├── create_map.php └── install.sh ├── php_foolphp.h ├── README.md ├── fool_object.c ├── foolphp.c ├── fool_application.c ├── fool_dispatcher.c ├── fool_config.c ├── fool_view.c ├── fool_loader.c ├── fool_request.c └── fool_controller.c /EXPERIMENTAL: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fool_exception.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_EXCEPTION_H 2 | #define PHP_FOOL_EXCEPTION_H 3 | 4 | 5 | #define FOOL_EXCEPTION_PROPERTY_NAME_INSTANCE "_instance" 6 | 7 | 8 | extern zend_class_entry *fool_exception_ce; 9 | 10 | void fool_throw_exception(long code,char* msg TSRMLS_DC); 11 | 12 | FOOL_STARTUP_MODULE(exception); 13 | #endif 14 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | // If your extension references something external, use ARG_WITH 5 | // ARG_WITH("foolphp", "for foolphp support", "no"); 6 | 7 | // Otherwise, use ARG_ENABLE 8 | // ARG_ENABLE("foolphp", "enable foolphp support", "no"); 9 | 10 | if (PHP_FOOLPHP != "no") { 11 | EXTENSION("foolphp", "foolphp.c"); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /fool_object.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_OBJECT_H 2 | #define PHP_FOOL_OBJECT_H 3 | 4 | 5 | #define FOOL_OBJECT_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_OBJECT_PROPERTY_NAME_LIST "_obj_list" 7 | 8 | 9 | 10 | extern zend_class_entry *fool_object_ce; 11 | zval* fool_object_instance(TSRMLS_D); 12 | 13 | FOOL_STARTUP_MODULE(object); 14 | #endif 15 | -------------------------------------------------------------------------------- /fool_application.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_APPLICATON_H 2 | #define PHP_FOOL_APPLICATON_H 3 | 4 | 5 | #define FOOL_APPLICATION_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_APPLICATION_PROPERTY_NAME_DISPATCHER "_dispatcher" 7 | #define FOOL_APPLICATION_PROPERTY_NAME_LOADER "_loader" 8 | 9 | 10 | extern zend_class_entry *fool_application_ce; 11 | 12 | zval* fool_application_instance(TSRMLS_D); 13 | 14 | FOOL_STARTUP_MODULE(application); 15 | #endif 16 | -------------------------------------------------------------------------------- /fool_loader.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_LOADER_H 2 | #define PHP_FOOL_LOADER_H 3 | 4 | 5 | #define FOOL_LOADER_PROPERTY_NAME_INSTANCE "_instance" 6 | 7 | 8 | extern zend_class_entry *fool_loader_ce; 9 | 10 | zval* fool_loader_instance(TSRMLS_D); 11 | int fool_loader_register_autoload(zval* loader TSRMLS_DC); 12 | int fool_loader_include(char* path TSRMLS_DC); 13 | int fool_loader_autoload(char* class_name TSRMLS_DC); 14 | 15 | FOOL_STARTUP_MODULE(loader); 16 | #endif 17 | -------------------------------------------------------------------------------- /fool_dispatcher.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_DISPATCHER_H 2 | #define PHP_FOOL_DISPATCHER_H 3 | 4 | 5 | #define FOOL_DISPATCHER_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_DISPATCHER_PROPERTY_NAME_REQUEST "_request" 7 | 8 | 9 | extern zend_class_entry *fool_dispatcher_ce; 10 | zval* fool_dispatcher_instance(TSRMLS_D); 11 | zval* fool_dispatcher_dispatch(zval* dispatcher TSRMLS_DC); 12 | zend_class_entry* fool_dispatcher_get_controller(char* controller_name TSRMLS_DC); 13 | 14 | FOOL_STARTUP_MODULE(dispatcher); 15 | #endif 16 | -------------------------------------------------------------------------------- /fool_config.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_CONFIG_H 2 | #define PHP_FOOL_CONFIG_H 3 | 4 | 5 | #define FOOL_CONFIG_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_CONFIG_PROPERTY_NAME_VAR "_config" 7 | 8 | 9 | 10 | extern zend_class_entry *fool_config_ce; 11 | 12 | int fool_config_get_defined_vars(char* config_path,zval* var_list TSRMLS_DC); 13 | int fool_config_init(TSRMLS_D); 14 | zval* fool_config_get(zval* object,char* class_name,int name_len TSRMLS_DC); 15 | 16 | FOOL_STARTUP_MODULE(config); 17 | #endif 18 | -------------------------------------------------------------------------------- /fool_controller.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_CONTROLLER_H 2 | #define PHP_FOOL_CONTROLLER_H 3 | 4 | 5 | #define FOOL_CONTROLLER_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_CONTROLLER_PROPERTY_NAME_REQUEST "_request" 7 | #define FOOL_CONTROLLER_PROPERTY_NAME_VIEW "_view" 8 | 9 | 10 | extern zend_class_entry *fool_controller_ce; 11 | 12 | int fool_controller_dispatch_handler(zend_class_entry* ce,zval* controller,zval* request,zval* view TSRMLS_DC); 13 | 14 | FOOL_STARTUP_MODULE(controller); 15 | #endif 16 | -------------------------------------------------------------------------------- /foolphp.php: -------------------------------------------------------------------------------- 1 | "; 3 | 4 | if(!extension_loaded('foolphp')) { 5 | dl('foolphp.' . PHP_SHLIB_SUFFIX); 6 | } 7 | $module = 'foolphp'; 8 | $functions = get_extension_funcs($module); 9 | echo "Functions available in the test extension:$br\n"; 10 | foreach($functions as $func) { 11 | echo $func."$br\n"; 12 | } 13 | echo "$br\n"; 14 | $function = 'confirm_' . $module . '_compiled'; 15 | if (extension_loaded($module)) { 16 | $str = $function($module); 17 | } else { 18 | $str = "Module $module is not compiled into PHP"; 19 | } 20 | echo "$str\n"; 21 | ?> 22 | -------------------------------------------------------------------------------- /fool_view.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_VIEW_H 2 | #define PHP_FOOL_VIEW_H 3 | 4 | 5 | #define FOOL_VIEW_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_VIEW_PROPERTY_NAME_VAR "_var" 7 | 8 | #define FOOL_VIEW_TPL_PATH "views" 9 | #define FOOL_VIEW_TPL_EXTENSION ".tpl.php" 10 | 11 | 12 | 13 | extern zend_class_entry *fool_view_ce; 14 | zval* fool_view_instance(TSRMLS_D); 15 | int fool_view_assign(zval* view,char* key,int key_len,zval* value TSRMLS_DC); 16 | int fool_view_render(zval* view,char* script,zval* ret,int out TSRMLS_DC); 17 | 18 | FOOL_STARTUP_MODULE(view); 19 | #endif 20 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check for foolphp presence 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 20 | --EXPECT-- 21 | foolphp extension is available 22 | -------------------------------------------------------------------------------- /fool_request.h: -------------------------------------------------------------------------------- 1 | #ifndef PHP_FOOL_REQUEST_H 2 | #define PHP_FOOL_REQUEST_H 3 | 4 | 5 | #define FOOL_REQUEST_PROPERTY_NAME_INSTANCE "_instance" 6 | #define FOOL_REQUEST_PROPERTY_NAME_CONTROLLER "controller" //handler控制器 7 | #define FOOL_REQUEST_PROPERTY_NAME_ACTION "action" //handler操作 8 | #define FOOL_REQUEST_PROPERTY_NAME_CONTROLLER_NAME "controller_name" //handler控制器 9 | #define FOOL_REQUEST_PROPERTY_NAME_ACTION_NAME "action_name" //handler操作 10 | 11 | #define FOOL_REQUEST_CONTROLLER_SUFIX "Controller" //控制器后缀 12 | #define FOOL_REQUEST_ACTION_SUFIX "Action" //操作后缀 13 | #define FOOL_REQUEST_CONTROLLER_DEFAULT "Index" //默认控制器 14 | #define FOOL_REQUEST_ACTION_DEFAULT "index" //默认操作 15 | #define FOOL_REQUEST_SEPARATOR "." //分隔符 16 | #define FOOL_REQUEST_METHOD_PARAM "m" 17 | 18 | 19 | 20 | 21 | 22 | extern zend_class_entry *fool_request_ce; 23 | zval* fool_request_instance(TSRMLS_D); 24 | zval* fool_request_get_controller(zval* request TSRMLS_DC); 25 | zval* fool_request_get_controller_name(zval* request TSRMLS_DC); 26 | zval* fool_request_get_action(zval* request TSRMLS_DC); 27 | zval* fool_request_get_action_name(zval* request TSRMLS_DC); 28 | int fool_request_parse_method(zval* request TSRMLS_DC); 29 | 30 | FOOL_STARTUP_MODULE(request); 31 | #endif 32 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | /* config.h. Generated from config.h.in by configure. */ 2 | /* config.h.in. Generated from configure.in by autoheader. */ 3 | 4 | /* Whether to build foolphp as dynamic module */ 5 | #define COMPILE_DL_FOOLPHP 1 6 | 7 | /* Define to 1 if you have the header file. */ 8 | #define HAVE_DLFCN_H 1 9 | 10 | /* Define to 1 if you have the header file. */ 11 | #define HAVE_INTTYPES_H 1 12 | 13 | /* Define to 1 if you have the header file. */ 14 | #define HAVE_MEMORY_H 1 15 | 16 | /* Define to 1 if you have the header file. */ 17 | #define HAVE_STDINT_H 1 18 | 19 | /* Define to 1 if you have the header file. */ 20 | #define HAVE_STDLIB_H 1 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #define HAVE_STRINGS_H 1 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #define HAVE_STRING_H 1 27 | 28 | /* Define to 1 if you have the header file. */ 29 | #define HAVE_SYS_STAT_H 1 30 | 31 | /* Define to 1 if you have the header file. */ 32 | #define HAVE_SYS_TYPES_H 1 33 | 34 | /* Define to 1 if you have the header file. */ 35 | #define HAVE_UNISTD_H 1 36 | 37 | /* Define to 1 if your C compiler doesn't accept -c and -o together. */ 38 | /* #undef NO_MINUS_C_MINUS_O */ 39 | 40 | /* Define to the address where bug reports for this package should be sent. */ 41 | #define PACKAGE_BUGREPORT "" 42 | 43 | /* Define to the full name of this package. */ 44 | #define PACKAGE_NAME "" 45 | 46 | /* Define to the full name and version of this package. */ 47 | #define PACKAGE_STRING "" 48 | 49 | /* Define to the one symbol short name of this package. */ 50 | #define PACKAGE_TARNAME "" 51 | 52 | /* Define to the version of this package. */ 53 | #define PACKAGE_VERSION "" 54 | 55 | /* Define to 1 if you have the ANSI C header files. */ 56 | #define STDC_HEADERS 1 57 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 2 | dnl config.m4 for extension foolphp 3 | 4 | dnl Comments in this file start with the string 'dnl'. 5 | dnl Remove where necessary. This file will not work 6 | dnl without editing. 7 | 8 | dnl If your extension references something external, use with: 9 | 10 | PHP_ARG_WITH(foolphp, for foolphp support, 11 | Make sure that the comment is aligned: 12 | [ --with-foolphp Include foolphp support]) 13 | 14 | dnl Otherwise use enable: 15 | 16 | dnl PHP_ARG_ENABLE(foolphp, whether to enable foolphp support, 17 | dnl Make sure that the comment is aligned: 18 | dnl [ --enable-foolphp Enable foolphp support]) 19 | 20 | if test "$PHP_FOOLPHP" != "no"; then 21 | dnl Write more examples of tests here... 22 | 23 | dnl # --with-foolphp -> check with-path 24 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this 25 | dnl SEARCH_FOR="/include/foolphp.h" # you most likely want to change this 26 | dnl if test -r $PHP_FOOLPHP/$SEARCH_FOR; then # path given as parameter 27 | dnl FOOLPHP_DIR=$PHP_FOOLPHP 28 | dnl else # search default path list 29 | dnl AC_MSG_CHECKING([for foolphp files in default path]) 30 | dnl for i in $SEARCH_PATH ; do 31 | dnl if test -r $i/$SEARCH_FOR; then 32 | dnl FOOLPHP_DIR=$i 33 | dnl AC_MSG_RESULT(found in $i) 34 | dnl fi 35 | dnl done 36 | dnl fi 37 | dnl 38 | dnl if test -z "$FOOLPHP_DIR"; then 39 | dnl AC_MSG_RESULT([not found]) 40 | dnl AC_MSG_ERROR([Please reinstall the foolphp distribution]) 41 | dnl fi 42 | 43 | dnl # --with-foolphp -> add include path 44 | dnl PHP_ADD_INCLUDE($FOOLPHP_DIR/include) 45 | 46 | dnl # --with-foolphp -> check for lib and symbol presence 47 | dnl LIBNAME=foolphp # you may want to change this 48 | dnl LIBSYMBOL=foolphp # you most likely want to change this 49 | 50 | dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 51 | dnl [ 52 | dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $FOOLPHP_DIR/lib, FOOLPHP_SHARED_LIBADD) 53 | dnl AC_DEFINE(HAVE_FOOLPHPLIB,1,[ ]) 54 | dnl ],[ 55 | dnl AC_MSG_ERROR([wrong foolphp lib version or lib not found]) 56 | dnl ],[ 57 | dnl -L$FOOLPHP_DIR/lib -lm 58 | dnl ]) 59 | dnl 60 | dnl PHP_SUBST(FOOLPHP_SHARED_LIBADD) 61 | 62 | PHP_NEW_EXTENSION(foolphp, foolphp.c fool_application.c fool_dispatcher.c fool_loader.c fool_request.c fool_controller.c fool_object.c fool_view.c fool_config.c fool_exception.c, $ext_shared) 63 | fi 64 | -------------------------------------------------------------------------------- /fool_exception.c: -------------------------------------------------------------------------------- 1 | /* $Id$ */ 2 | 3 | #ifdef HAVE_CONFIG_H 4 | #include "config.h" 5 | #endif 6 | 7 | #include "php.h" 8 | #include "php_ini.h" 9 | #include "ext/standard/info.h" 10 | #include "Zend/zend_exceptions.h" 11 | #include "php_foolphp.h" 12 | 13 | #include "fool_application.h" 14 | #include "fool_dispatcher.h" 15 | #include "fool_loader.h" 16 | #include "fool_request.h" 17 | #include "fool_controller.h" 18 | #include "fool_object.h" 19 | #include "fool_view.h" 20 | #include "fool_config.h" 21 | #include "fool_exception.h" 22 | 23 | zend_class_entry* fool_exception_ce; 24 | 25 | /*#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)*/ 26 | ZEND_BEGIN_ARG_INFO_EX(fool_exception_construct_arginfo, 0, 0, 0) 27 | ZEND_END_ARG_INFO() 28 | 29 | /*{{{ void fool_throw_exception(long code,char* msg TSRMLS_DC) 30 | */ 31 | void fool_throw_exception(long code,char* msg TSRMLS_DC) 32 | { 33 | zend_throw_exception(fool_exception_ce,msg,code TSRMLS_CC); 34 | } 35 | /*}}}*/ 36 | 37 | /*{{{ zend_class_entry * fool_get_exception_base(int root TSRMLS_DC) 38 | * copy from yaf 39 | */ 40 | zend_class_entry * fool_get_exception_base(int root TSRMLS_DC) { 41 | #if can_handle_soft_dependency_on_SPL && defined(HAVE_SPL) && ((PHP_MAJOR_VERSION > 5) || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 1)) 42 | if (!root) { 43 | if (!spl_ce_RuntimeException) { 44 | zend_class_entry **pce; 45 | if (zend_hash_find(CG(class_table), "runtimeexception", sizeof("RuntimeException"), (void **) &pce) == SUCCESS) { 46 | spl_ce_RuntimeException = *pce; 47 | return *pce; 48 | } 49 | } else { 50 | return spl_ce_RuntimeException; 51 | } 52 | } 53 | #endif 54 | 55 | #if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) 56 | return zend_exception_get_default(); 57 | #else 58 | return zend_exception_get_default(TSRMLS_C); 59 | #endif 60 | } 61 | /*}}}*/ 62 | 63 | /*{{{ Fool_Application::__construct(void) 64 | */ 65 | PHP_METHOD(fool_exception,__construct) 66 | { 67 | } 68 | /*}}}*/ 69 | 70 | zend_function_entry fool_exception_methods[] = { 71 | ZEND_ME(fool_exception,__construct,fool_exception_construct_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) 72 | PHP_FE_END /* Must be the last line in qpclass_functions[] */ 73 | }; 74 | 75 | FOOL_STARTUP_MODULE(exception) 76 | { 77 | zend_class_entry ce; 78 | INIT_CLASS_ENTRY(ce,"Fool_Exception",fool_exception_methods); 79 | 80 | fool_exception_ce = zend_register_internal_class_ex(&ce,fool_get_exception_base(0 TSRMLS_CC),NULL TSRMLS_CC); 81 | 82 | zend_declare_property_null(fool_exception_ce,ZEND_STRL(FOOL_EXCEPTION_PROPERTY_NAME_INSTANCE),ZEND_ACC_PRIVATE|ZEND_ACC_STATIC TSRMLS_CC); 83 | 84 | return SUCCESS; 85 | } 86 | 87 | 88 | /* 89 | * Local variables: 90 | * tab-width: 4 91 | * c-basic-offset: 4 92 | * End: 93 | * vim600: noet sw=4 ts=4 fdm=marker 94 | * vim<600: noet sw=4 ts=4 95 | */ 96 | -------------------------------------------------------------------------------- /tools/create_map.php: -------------------------------------------------------------------------------- 1 | run($application_path,$config_path,$scan_dir); 8 | if(true === $r) break; 9 | } 10 | 11 | class Autoload 12 | { 13 | private $filter = array('views'); 14 | private $map_value_name = '$fool_php_class_map'; 15 | 16 | public function run($app_root,$config_root,$scan_dir) 17 | {/*{{{*/ 18 | $list = array(); 19 | 20 | foreach($scan_dir as $_dir){ 21 | $_list = $this->scanFile($app_root . '/' . $_dir); 22 | if(empty($_list)) continue; 23 | $list = array_merge($list,$_list); 24 | } 25 | $tpl = "\t'%s' => '%s',\n"; 26 | 27 | $content_tpl = "$path){ 32 | $d .= sprintf($tpl,$class_name,$path); 33 | echo $n,".Find Class [ $class_name ] in \"$path\"\n"; 34 | ++$n; 35 | } 36 | 37 | $content = sprintf($content_tpl,date('Y/m/d H:i:s',time()),$this->map_value_name,$d); 38 | 39 | $key = md5($content); 40 | 41 | $map_path = $config_root . '/' . ini_get('foolphp.class_map'); 42 | $fp = fopen($map_path,"w"); 43 | if(!$fp){ 44 | echo "无法写入文件:" . $map_path . ",请检查目录的读写权限!\n"; 45 | exit; 46 | return false; 47 | } 48 | fwrite($fp,$content); 49 | 50 | fclose($fp); 51 | 52 | $_key = md5(file_get_contents($map_path)); 53 | 54 | if($key == $_key){ 55 | echo "\n====================[success]===================\nfinish to build class map!\n"; 56 | return true; 57 | }else{ 58 | return false; 59 | } 60 | }/*}}}*/ 61 | 62 | public function scanFile($directory) 63 | {/*{{{*/ 64 | if(!is_dir($directory)) return array(); 65 | $arr = array(); 66 | $mydir = dir($directory); 67 | while($file = $mydir->read()) 68 | { 69 | if((is_dir("$directory/$file")) && $file!="." && $file!=".." && !in_array($file,$this->filter)) 70 | { 71 | $res = $this->scanFile("$directory/$file"); 72 | $arr = array_merge($arr, $res); 73 | }else if(strpos($file,'.') !== 0){ 74 | $file_path = $directory."/".$file; 75 | $file_info = pathinfo($file_path); 76 | if(isset($file_info['extension']) && $file_info['extension'] == 'php') 77 | { 78 | $classes = $this->getClassName($file_path); 79 | foreach($classes as $class) 80 | { 81 | $arr[$class] = $file_info['dirname'].'/'.$file_info['basename']; 82 | } 83 | } 84 | } 85 | } 86 | $mydir->close(); 87 | return $arr; 88 | }/*}}}*/ 89 | 90 | public function getClassName($file) 91 | {/*{{{*/ 92 | $lines = file($file); 93 | $class = array(); 94 | foreach($lines as $line) 95 | { 96 | if(preg_match("/^\s*[cC]lass\s+(\S+)\s*/",$line,$match)) $class[] = trim($match[1],"{"); 97 | if (preg_match("/^\s*abstract\s*class\s+(\S+)\s*/", $line, $match)) $class[] = trim($match[1],"{"); 98 | if (preg_match("/^\s*interface\s+(\S+)\s*/", $line, $match)) $class[] = trim($match[1],"{"); 99 | } 100 | return $class; 101 | }/*}}}*/ 102 | 103 | } 104 | -------------------------------------------------------------------------------- /php_foolphp.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2013 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_FOOLPHP_H 22 | #define PHP_FOOLPHP_H 23 | 24 | extern zend_module_entry foolphp_module_entry; 25 | #define phpext_foolphp_ptr &foolphp_module_entry 26 | 27 | #define PHP_FOOLPHP_VERSION "1.0.0" /* Replace with version number for your extension */ 28 | 29 | #ifdef PHP_WIN32 30 | # define PHP_FOOLPHP_API __declspec(dllexport) 31 | #elif defined(__GNUC__) && __GNUC__ >= 4 32 | # define PHP_FOOLPHP_API __attribute__ ((visibility("default"))) 33 | #else 34 | # define PHP_FOOLPHP_API 35 | #endif 36 | 37 | #ifdef ZTS 38 | #include "TSRM.h" 39 | #endif 40 | 41 | #define FOOL_STARTUP_MODULE(module) ZEND_MINIT_FUNCTION(foolphp_##module) 42 | #define FOOL_STARTUP(module) ZEND_MODULE_STARTUP_N(foolphp_##module)(INIT_FUNC_ARGS_PASSTHRU) 43 | 44 | #define FOOL_CLASS_MAP_VAR "fool_php_class_map" 45 | 46 | 47 | PHP_MINIT_FUNCTION(foolphp); 48 | PHP_MSHUTDOWN_FUNCTION(foolphp); 49 | PHP_RINIT_FUNCTION(foolphp); 50 | PHP_RSHUTDOWN_FUNCTION(foolphp); 51 | PHP_MINFO_FUNCTION(foolphp); 52 | 53 | 54 | ZEND_BEGIN_MODULE_GLOBALS(foolphp) 55 | char *application_path; 56 | char *config_path; 57 | char *class_map; 58 | char *config_name; 59 | ZEND_END_MODULE_GLOBALS(foolphp) 60 | 61 | extern ZEND_DECLARE_MODULE_GLOBALS(foolphp); 62 | extern PHPAPI void php_debug_zval_dump(zval **struc, int level TSRMLS_DC); 63 | 64 | 65 | 66 | 67 | /* In every utility function you add that needs to use variables 68 | in php_foolphp_globals, call TSRMLS_FETCH(); after declaring other 69 | variables used by that function, or better yet, pass in TSRMLS_CC 70 | after the last function argument and declare your utility function 71 | with TSRMLS_DC after the last declared argument. Always refer to 72 | the globals in your function as FOOLPHP_G(variable). You are 73 | encouraged to rename these macros something shorter, see 74 | examples in any other php module directory. 75 | */ 76 | 77 | #ifdef ZTS 78 | #define FOOLPHP_G(v) TSRMG(foolphp_globals_id, zend_foolphp_globals *, v) 79 | #else 80 | #define FOOLPHP_G(v) (foolphp_globals.v) 81 | #endif 82 | 83 | #endif /* PHP_FOOLPHP_H */ 84 | 85 | 86 | /* 87 | * Local variables: 88 | * tab-width: 4 89 | * c-basic-offset: 4 90 | * End: 91 | * vim600: noet sw=4 ts=4 fdm=marker 92 | * vim<600: noet sw=4 ts=4 93 | */ 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FoolPHP 2 | PHP扩展实现的轻量级MVC框架 3 | 4 | [php7版本>>](https://github.com/pangudashu/FoolPHP7) 5 | 6 | ### 说明 7 | 8 | FoolPHP是在学习PHP扩展开发的过程中作为练习作业同时阅读参考Yaf而实现的,所以有些代码就是Yaf的。[@Laruence](http://www.laruence.com/) [@Walu](http://www.walu.cc/) 9 | 10 | 这个框架的比较简洁,仅实现最核心的dispatcher。 11 | 12 | ### 特点 13 | 14 | * 简洁 15 | * 不限制任何类名、文件名、目录,通过预处理的方式将类名及其所在的文件加入autoload 16 | * 类自动加载 17 | * 原生php模板引擎 18 | 19 | ### 安装 20 | 从github下载源码后解压,如解压后目录:FoolPHP-1.0.0 21 | cd FoolPHP-1.0.0 22 | phpize 23 | ./configure 24 | make && make install 25 | 26 | 最后将extension=foolphp.so加入php.ini,重启php-fpm或者其他fastcgi 27 | 28 | ### 初始化项目 29 | 30 | 1.新建一个目录,如/websites,将FoolPHP源码下tools目录复制到/websites目录下 31 | 32 | 2.执行sh tools/install.sh 33 | 34 | 成功后/websites下多了一个src目录,/websites/src结构: 35 | 36 | ├── application
37 | │   ├── controllers
38 | │   │   └── DemoController.php
39 | │   ├── models
40 | │   │   └── DemoModel.php
41 | │   └── views
42 | │   ├── Common
43 | │   │   ├── footer.tpl.php
44 | │   │   └── header.tpl.php
45 | │   └── Demo
46 | │   └── index.tpl.php
47 | ├── config
48 | │   ├── config.inc.php
49 | │   └── fool_php_class.map
50 | └── www
51 | | └── index.php
52 | 53 | 3./websites/src/www为web访问目录,配置web服务器root :/websites/src/www,访问:http://Domain/index.php?m=demo.index 54 | 55 | ### tools工具包 56 | 1. install.sh新项目初始化脚本 57 | 58 | 2. config.php预处理类配置文件,$application_path值为application目录:/your_websites/src/application,$config_path为配置文件目录:/your_websites/src/config,$scan_dir为自动加载类扫描目录,相对于$application_path的目录名,如controllers、models、librarys 59 | 60 | 3. create_map.php预处理类生成脚本,它会扫描config.php中配置的$scan_dir目录下的php文件,生成"类名 => 文件路径"的记录到$config_path/fool_php_class.map文件中,这将是使用最频繁的文件,当新增/修改/删除文件、类、目录时都要重新执行此脚本,否则将会运行出错 61 | 62 | 使用此脚本执行 php create_map.php即可 63 | 64 | # 使用手册 65 | 66 | ### 入口文件 67 | //index.php,使用install.sh初始化的项目此文件位于/website/src/www/index.php 68 | run(); 74 | 75 | APPLICATION_PATH : 应用目录 76 | CONFIG_PATH : 配置文件目录 77 | 78 | ### 路由 79 | 框架提供最简单的通过GET参数分发路由(/?m=controller.action),没有实现rewrite、正则等路由协议 80 | 81 | ### 控制器 82 | 控制器名以Controller为后缀,文件名没有要求,可以是任意名称,只要继承了Fool_Controller的类就是一个控制器,控制器中操作(Action)作为请求处理的handler,通过/?m=controller.action访问将dispatch到此Action,操作的命名以Action为后缀 83 | 84 | assign("content",$this->getContent()); 88 | $this->display(); 89 | } 90 | 91 | private function getContent(){ 92 | return "Hi~"; 93 | } 94 | } 95 | ?> 96 | 97 | 在控制中有两个前后置函数:preDispatch()、afterDispatch()分别在Action执行前后调用 98 | 99 | 控制器方法 100 | 101 | assign(string $key,void $value) 模板赋值 102 | render([string $tpl_script]) 渲染模板,将结果返回,不传参数默认调用views路径下"控制器/操作.tpl.php" 103 | display([string $tpl_script]) 渲染模板,结果直接输出 104 | getController(void) 获取当前控制器名 105 | getMethod(void) 获取当前操作名 106 | 107 | ### 配置 108 | CONFIG_PATH下有两个配置文件:项目配置(config.inc.php)、自动加载类配置(fool_php_class.map),其中fool_php_class.map由tools/create_map.php脚本自动更新 109 | 110 | config.inc.php配置文件格式为普通的key=>value: 111 | 112 | '127.0.0.1', 116 | 'user' => 'root', 117 | 'pass' => '', 118 | 'port' => 3306, 119 | ); 120 | 121 | 在项目中通过Fool_Config::find(string $key)获取配置 122 | 123 | ### 视图 124 | 框架使用php作为模板引擎,视图文件后缀.tpl.php,目录:/websites/src/application/views,这个值在模板中可以通过$VIEW_PATH变量获取(嵌套模板时将会用到) 125 | 126 | views目录下可以按控制器划分子目录 127 | 128 | ### 自动加载 129 | FoolPHP使用spl_autoload_register实现自动加载,当实例化一个类时,如果在EG(class_table)哈希表中找不到这个类将调用注册的钩子函数,根据CONFIG_PATH下的fool_php_class.map找到这个类所在的文件,然后include 130 | 131 | 所以当项目中新增、修改类时都需要执行"php tools/create_map.php"重新生成fool_php_class.map,这种方式使得项目的目录设置更灵活 132 | 133 | 在项目中可以通过普通的方式实例化一个类:$user = new UserModel(); 134 | 135 | 同时框架提供了一个方法生成单例:Fool_Object::find(string $className) 136 | 137 | ### 异常 138 | 框架中一些错误通过异常的方式返回,可以在入口文件中捕捉到进行处理: 139 | 140 | try{ 141 | $application = Fool_Application::getInstance(APPLICATION_PATH,CONFIG_PATH); 142 | $application->run(); 143 | }catch(Fool_Exception $e){ 144 | echo $e->getCode(),$e->getMessage(); 145 | } 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /fool_object.c: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #include "php.h" 6 | #include "php_ini.h" 7 | #include "ext/standard/info.h" 8 | #include "Zend/zend_interfaces.h" 9 | #include "php_foolphp.h" 10 | 11 | #include "fool_application.h" 12 | #include "fool_dispatcher.h" 13 | #include "fool_loader.h" 14 | #include "fool_request.h" 15 | #include "fool_controller.h" 16 | #include "fool_object.h" 17 | #include "fool_view.h" 18 | #include "fool_config.h" 19 | #include "fool_exception.h" 20 | 21 | zend_class_entry* fool_object_ce; 22 | 23 | 24 | ZEND_BEGIN_ARG_INFO_EX(fool_object_construct_arginfo, 0, 0, 0) 25 | ZEND_END_ARG_INFO() 26 | 27 | ZEND_BEGIN_ARG_INFO_EX(fool_object_find_arginfo, 0, 0, 1) 28 | ZEND_ARG_INFO(0, class_name) 29 | ZEND_END_ARG_INFO() 30 | 31 | 32 | /**{{{ zval* get_instance(TSRMLS_D) 33 | */ 34 | zval* fool_object_instance(TSRMLS_D) 35 | { 36 | zval* instance; 37 | zval* obj_list; 38 | 39 | instance = zend_read_static_property(fool_object_ce,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC); 40 | 41 | if(Z_TYPE_P(instance) == IS_OBJECT){ 42 | //Z_ADDREF_P(instance); //????????????????? 43 | return instance; 44 | } 45 | 46 | object_init_ex(instance,fool_object_ce); 47 | 48 | zend_update_static_property(fool_object_ce,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC); 49 | 50 | 51 | if(instance){ 52 | //初始化obj_list 53 | MAKE_STD_ZVAL(obj_list); 54 | array_init(obj_list); 55 | 56 | //add_next_index_long(obj_list,12345678); 57 | zend_update_property(fool_object_ce,instance,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_LIST),obj_list TSRMLS_CC); 58 | 59 | return instance; 60 | } 61 | } 62 | /*}}}*/ 63 | 64 | /*{{{ zval* fool_object_get(zval* object,char* class_name,int name_len TSRMLS_DC) 65 | */ 66 | zval* fool_object_get(zval* object,char* class_name,int name_len TSRMLS_DC) 67 | { 68 | zval* obj_list = zend_read_property(fool_object_ce,object,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_LIST),1 TSRMLS_CC); 69 | if(!obj_list){ 70 | return NULL; 71 | } 72 | 73 | zval** _obj; 74 | if(zend_hash_find(Z_ARRVAL_P(obj_list),class_name,name_len+1,(void**)&_obj) == FAILURE){ 75 | return NULL; 76 | } 77 | return *_obj; 78 | } 79 | /*}}}*/ 80 | 81 | /*{{{ int fool_object_set(zval* object,char* class_name,int name_len,zval* value TSRMLS_DC) 82 | */ 83 | int fool_object_set(zval* object,char* class_name,int name_len,zval* value TSRMLS_DC) 84 | { 85 | zval* obj_list = zend_read_property(fool_object_ce,object,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_LIST),1 TSRMLS_CC); 86 | if(!obj_list){ 87 | return 0; 88 | } 89 | 90 | Z_ADDREF_P(value); 91 | zend_hash_add(Z_ARRVAL_P(obj_list),class_name,name_len + 1, &value, sizeof(zval*), NULL); 92 | return 1; 93 | } 94 | /*}}}*/ 95 | 96 | /*{{{ public Fool_Object::__construct(void) 97 | */ 98 | PHP_METHOD(fool_object,__construct) 99 | { 100 | } 101 | /*}}}*/ 102 | 103 | /*{{{ public Fool_Object::find(string $class) 104 | */ 105 | PHP_METHOD(fool_object,find) 106 | { 107 | char* class_name; 108 | int class_name_len; 109 | 110 | if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&class_name,&class_name_len) == FAILURE){ 111 | RETURN_FALSE; 112 | } 113 | 114 | zval* object = zend_read_static_property(fool_object_ce,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC); 115 | zval* find_obj; 116 | find_obj = fool_object_get(object,class_name,class_name_len); 117 | 118 | if(find_obj){ 119 | RETURN_ZVAL(find_obj,1,0); 120 | } 121 | 122 | zend_class_entry* find_class_ce = fool_dispatcher_get_controller(class_name TSRMLS_CC); 123 | if(!find_class_ce){ 124 | RETURN_FALSE; 125 | } 126 | MAKE_STD_ZVAL(find_obj); 127 | object_init_ex(find_obj,find_class_ce); 128 | 129 | //save object 130 | fool_object_set(object,class_name,class_name_len,find_obj); 131 | 132 | RETURN_ZVAL(find_obj,1,0); 133 | } 134 | /*}}}*/ 135 | 136 | 137 | zend_function_entry fool_object_methods[] = { 138 | ZEND_ME(fool_object,__construct,fool_object_construct_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) 139 | ZEND_ME(fool_object,find,fool_object_find_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) 140 | PHP_FE_END /* Must be the last line in qpclass_functions[] */ 141 | }; 142 | 143 | 144 | FOOL_STARTUP_MODULE(object) 145 | { 146 | zend_class_entry ce; 147 | INIT_CLASS_ENTRY(ce,"Fool_Object",fool_object_methods); 148 | 149 | fool_object_ce = zend_register_internal_class(&ce TSRMLS_CC); 150 | 151 | zend_declare_property_null(fool_object_ce,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_INSTANCE),ZEND_ACC_PUBLIC|ZEND_ACC_STATIC TSRMLS_CC); 152 | zend_declare_property_null(fool_object_ce,ZEND_STRL(FOOL_OBJECT_PROPERTY_NAME_LIST),ZEND_ACC_PRIVATE|ZEND_ACC_STATIC TSRMLS_CC); 153 | 154 | return SUCCESS; 155 | } 156 | 157 | 158 | /* 159 | * Local variables: 160 | * tab-width: 4 161 | * c-basic-offset: 4 162 | * End: 163 | * vim600: noet sw=4 ts=4 fdm=marker 164 | * vim<600: noet sw=4 ts=4 165 | */ 166 | -------------------------------------------------------------------------------- /foolphp.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2013 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "php_ini.h" 27 | #include "ext/standard/info.h" 28 | #include "php_foolphp.h" 29 | 30 | #include "fool_application.h" 31 | #include "fool_dispatcher.h" 32 | #include "fool_loader.h" 33 | #include "fool_request.h" 34 | #include "fool_controller.h" 35 | #include "fool_object.h" 36 | #include "fool_view.h" 37 | #include "fool_config.h" 38 | #include "fool_exception.h" 39 | 40 | ZEND_DECLARE_MODULE_GLOBALS(foolphp); 41 | 42 | const zend_function_entry foolphp_functions[] = { 43 | PHP_FE_END /* Must be the last line in fool_functions[] */ 44 | }; 45 | 46 | zend_module_entry foolphp_module_entry = { 47 | #if ZEND_MODULE_API_NO >= 20010901 48 | STANDARD_MODULE_HEADER, 49 | #endif 50 | "foolphp", 51 | foolphp_functions, 52 | PHP_MINIT(foolphp), 53 | PHP_MSHUTDOWN(foolphp), 54 | PHP_RINIT(foolphp), /* Replace with NULL if there's nothing to do at request start */ 55 | PHP_RSHUTDOWN(foolphp), /* Replace with NULL if there's nothing to do at request end */ 56 | PHP_MINFO(foolphp), 57 | #if ZEND_MODULE_API_NO >= 20010901 58 | PHP_FOOLPHP_VERSION, 59 | #endif 60 | STANDARD_MODULE_PROPERTIES 61 | }; 62 | 63 | #ifdef COMPILE_DL_FOOLPHP 64 | ZEND_GET_MODULE(foolphp) 65 | #endif 66 | 67 | 68 | /* {{{ PHP_INI 69 | */ 70 | PHP_INI_BEGIN() 71 | STD_PHP_INI_ENTRY("foolphp.class_map","fool_php_class.map", PHP_INI_ALL,OnUpdateString,class_map, zend_foolphp_globals, foolphp_globals) 72 | STD_PHP_INI_ENTRY("foolphp.config_name","config.inc.php", PHP_INI_ALL,OnUpdateString,config_name, zend_foolphp_globals, foolphp_globals) 73 | PHP_INI_END(); 74 | /* }}} */ 75 | 76 | /* {{{ PHP_GINIT_FUNCTION(fool) 77 | */ 78 | PHP_GINIT_FUNCTION(foolphp) 79 | { 80 | foolphp_globals->application_path = NULL; 81 | foolphp_globals->config_path = NULL; 82 | } 83 | /* }}} */ 84 | 85 | /*{{{ PHP_MINIT_FUNCTION(foolphp) 86 | */ 87 | PHP_MINIT_FUNCTION(foolphp) 88 | { 89 | //register php.ini 90 | REGISTER_INI_ENTRIES(); 91 | 92 | FOOL_STARTUP(application); 93 | FOOL_STARTUP(dispatcher); 94 | FOOL_STARTUP(loader); 95 | FOOL_STARTUP(request); 96 | FOOL_STARTUP(controller); 97 | FOOL_STARTUP(object); 98 | FOOL_STARTUP(view); 99 | FOOL_STARTUP(config); 100 | FOOL_STARTUP(exception); 101 | 102 | return SUCCESS; 103 | } 104 | /*}}}*/ 105 | 106 | /* {{{ PHP_MSHUTDOWN_FUNCTION 107 | */ 108 | PHP_MSHUTDOWN_FUNCTION(foolphp) 109 | { 110 | return SUCCESS; 111 | } 112 | /* }}} */ 113 | 114 | /* {{{ PHP_RINIT_FUNCTION 115 | */ 116 | PHP_RINIT_FUNCTION(foolphp) 117 | { 118 | return SUCCESS; 119 | } 120 | /* }}} */ 121 | 122 | /* {{{ PHP_RSHUTDOWN_FUNCTION 123 | */ 124 | PHP_RSHUTDOWN_FUNCTION(foolphp) 125 | { 126 | if(FOOLPHP_G(application_path)){ 127 | efree(FOOLPHP_G(application_path)); 128 | } 129 | if(FOOLPHP_G(config_path)){ 130 | efree(FOOLPHP_G(config_path)); 131 | } 132 | 133 | return SUCCESS; 134 | } 135 | /* }}} */ 136 | 137 | /* {{{ PHP_MINFO_FUNCTION 138 | */ 139 | PHP_MINFO_FUNCTION(foolphp) 140 | { 141 | php_info_print_table_start(); 142 | php_info_print_table_header(2, "Foolphp Support", "enabled"); 143 | php_info_print_table_header(2, "Foolphp Version", PHP_FOOLPHP_VERSION); 144 | php_info_print_table_header(2, "Foolphp Class_map", FOOLPHP_G(class_map)); 145 | php_info_print_table_header(2, "Foolphp Config_name", FOOLPHP_G(config_name)); 146 | php_info_print_table_end(); 147 | 148 | /* Remove comments if you have entries in php.ini 149 | DISPLAY_INI_ENTRIES(); 150 | */ 151 | } 152 | /* }}} */ 153 | 154 | /* 155 | * Local variables: 156 | * tab-width: 4 157 | * c-basic-offset: 4 158 | * End: 159 | * vim600: noet sw=4 ts=4 fdm=marker 160 | * vim<600: noet sw=4 ts=4 161 | */ 162 | -------------------------------------------------------------------------------- /fool_application.c: -------------------------------------------------------------------------------- 1 | /* $Id$ */ 2 | 3 | #ifdef HAVE_CONFIG_H 4 | #include "config.h" 5 | #endif 6 | 7 | #include "php.h" 8 | #include "php_ini.h" 9 | #include "ext/standard/info.h" 10 | #include "Zend/zend_exceptions.h" 11 | #include "php_foolphp.h" 12 | 13 | #include "fool_application.h" 14 | #include "fool_dispatcher.h" 15 | #include "fool_loader.h" 16 | #include "fool_request.h" 17 | #include "fool_controller.h" 18 | #include "fool_object.h" 19 | #include "fool_view.h" 20 | #include "fool_config.h" 21 | #include "fool_exception.h" 22 | 23 | zend_class_entry* fool_application_ce; 24 | 25 | /*ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args)*/ 26 | ZEND_BEGIN_ARG_INFO_EX(fool_application_construct_arginfo, 0, 0, 0) 27 | ZEND_END_ARG_INFO() 28 | 29 | ZEND_BEGIN_ARG_INFO_EX(fool_application_getinstance_arginfo, 0, 0, 2) 30 | ZEND_ARG_INFO(0, application_path) 31 | ZEND_ARG_INFO(0, config_path) 32 | ZEND_END_ARG_INFO() 33 | 34 | ZEND_BEGIN_ARG_INFO_EX(fool_application_run_arginfo, 0, 0, 0) 35 | ZEND_END_ARG_INFO() 36 | 37 | 38 | /*{{{ zval* fool_application_instance(TSRMLS_D) 39 | */ 40 | zval* fool_application_instance(TSRMLS_D) 41 | { 42 | zval* instance; 43 | zval* dispatcher; 44 | zval* loader; 45 | 46 | instance = zend_read_static_property(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC); 47 | 48 | if(Z_TYPE_P(instance) == IS_OBJECT){ 49 | //Z_ADDREF_P(instance); 50 | return instance; 51 | } 52 | 53 | object_init_ex(instance,fool_application_ce); 54 | 55 | zend_update_static_property(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC); 56 | 57 | 58 | if(instance){ 59 | //init dispatcher 60 | dispatcher = fool_dispatcher_instance(TSRMLS_C); 61 | if(!dispatcher){ 62 | return NULL; 63 | } 64 | 65 | loader = fool_loader_instance(TSRMLS_CC); 66 | if(!loader){ 67 | return NULL; 68 | } 69 | fool_loader_register_autoload(loader TSRMLS_CC); 70 | 71 | zend_update_property(fool_application_ce,instance,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_DISPATCHER),dispatcher TSRMLS_CC); 72 | 73 | //init config 74 | fool_config_init(TSRMLS_C); 75 | //init object 76 | fool_object_instance(TSRMLS_C); 77 | 78 | return instance; 79 | } 80 | return NULL; 81 | } 82 | /*}}}*/ 83 | 84 | /*{{{ Fool_Application::__construct(void) 85 | */ 86 | PHP_METHOD(fool_application,__construct) 87 | { 88 | } 89 | /*}}}*/ 90 | 91 | /*{{{ public Fool_Application::getInstance(string $application_path,string $config_path) 92 | */ 93 | PHP_METHOD(fool_application,getInstance) 94 | { 95 | char* application_path; 96 | char* config_path; 97 | int application_path_len; 98 | int config_path_len; 99 | 100 | if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"ss",&application_path,&application_path_len,&config_path,&config_path_len) == FAILURE){ 101 | fool_throw_exception(104,"[Warn]Fool_Application::getInstance(string $application_path,string $config_path)" TSRMLS_CC); 102 | RETURN_FALSE; 103 | } 104 | 105 | FOOLPHP_G(application_path) = estrndup(application_path,application_path_len); 106 | FOOLPHP_G(config_path) = estrndup(config_path,config_path_len); 107 | 108 | zval* instance = fool_application_instance(TSRMLS_C); 109 | 110 | if(instance){ 111 | RETURN_ZVAL(instance,1,0); 112 | } 113 | RETURN_FALSE; 114 | } 115 | /*}}}*/ 116 | 117 | /*{{{ public Fool_Application::run(void) 118 | */ 119 | PHP_METHOD(fool_application,run) 120 | { 121 | zval* response; 122 | zval* dispatcher; 123 | 124 | zval* self = getThis(); 125 | 126 | 127 | dispatcher = zend_read_property(fool_application_ce,self,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_DISPATCHER),1 TSRMLS_CC); 128 | if((response = fool_dispatcher_dispatch(dispatcher TSRMLS_CC))){ 129 | RETURN_ZVAL(response,1,1); 130 | } 131 | RETURN_FALSE; 132 | } 133 | /*}}}*/ 134 | 135 | 136 | zend_function_entry fool_application_methods[] = { 137 | ZEND_ME(fool_application,__construct,fool_application_construct_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) 138 | ZEND_ME(fool_application,getInstance,fool_application_getinstance_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) 139 | ZEND_ME(fool_application,run,fool_application_run_arginfo,ZEND_ACC_PUBLIC) 140 | PHP_FE_END /* Must be the last line in qpclass_functions[] */ 141 | }; 142 | 143 | FOOL_STARTUP_MODULE(application) 144 | { 145 | zend_class_entry ce; 146 | INIT_CLASS_ENTRY(ce,"Fool_Application",fool_application_methods); 147 | 148 | fool_application_ce = zend_register_internal_class(&ce TSRMLS_CC); 149 | 150 | zend_declare_property_null(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_INSTANCE),ZEND_ACC_PRIVATE|ZEND_ACC_STATIC TSRMLS_CC); 151 | zend_declare_property_null(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_DISPATCHER),ZEND_ACC_PRIVATE TSRMLS_CC); 152 | zend_declare_property_null(fool_application_ce,ZEND_STRL(FOOL_APPLICATION_PROPERTY_NAME_LOADER),ZEND_ACC_PRIVATE TSRMLS_CC); 153 | 154 | return SUCCESS; 155 | } 156 | 157 | 158 | /* 159 | * Local variables: 160 | * tab-width: 4 161 | * c-basic-offset: 4 162 | * End: 163 | * vim600: noet sw=4 ts=4 fdm=marker 164 | * vim<600: noet sw=4 ts=4 165 | */ 166 | -------------------------------------------------------------------------------- /fool_dispatcher.c: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #include "php.h" 6 | #include "php_ini.h" 7 | #include "Zend/zend_interfaces.h" 8 | #include "ext/standard/php_string.h" 9 | #include "ext/standard/info.h" 10 | #include "php_foolphp.h" 11 | 12 | #include "fool_application.h" 13 | #include "fool_dispatcher.h" 14 | #include "fool_loader.h" 15 | #include "fool_request.h" 16 | #include "fool_controller.h" 17 | #include "fool_object.h" 18 | #include "fool_view.h" 19 | #include "fool_config.h" 20 | #include "fool_exception.h" 21 | 22 | 23 | zend_class_entry* fool_dispatcher_ce; 24 | 25 | 26 | ZEND_BEGIN_ARG_INFO_EX(fool_dispatcher_getinstance_arginfo, 0, 0, 0) 27 | ZEND_END_ARG_INFO() 28 | 29 | ZEND_BEGIN_ARG_INFO_EX(fool_dispatcher_construct_arginfo, 0, 0, 0) 30 | ZEND_END_ARG_INFO() 31 | 32 | 33 | /**{{{ zval* get_instance(TSRMLS_D) 34 | */ 35 | zval* fool_dispatcher_instance(TSRMLS_D) 36 | { 37 | zval* instance; 38 | 39 | instance = zend_read_static_property(fool_dispatcher_ce,ZEND_STRL(FOOL_DISPATCHER_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC); 40 | 41 | if(Z_TYPE_P(instance) == IS_OBJECT){ 42 | //Z_ADDREF_P(instance); //????????????????? 43 | return instance; 44 | } 45 | 46 | object_init_ex(instance,fool_dispatcher_ce); 47 | 48 | zend_update_static_property(fool_dispatcher_ce,ZEND_STRL(FOOL_DISPATCHER_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC); 49 | 50 | 51 | if(instance){ 52 | return instance; 53 | } 54 | } 55 | /*}}}*/ 56 | 57 | /*{{{ zend_class_entry* fool_dispatcher_get_controller(char* controller_name TSRMLS_DC) 58 | */ 59 | zend_class_entry* fool_dispatcher_get_controller(char* controller_name TSRMLS_DC) 60 | { 61 | zend_class_entry **ce = NULL; 62 | int clen = strlen(controller_name); 63 | char* controller_name_lower = estrdup(controller_name); 64 | 65 | php_strtolower(controller_name_lower,clen); 66 | 67 | if(zend_hash_find(EG(class_table),controller_name_lower,clen+1,(void**)&ce TSRMLS_CC) == SUCCESS){ 68 | return *ce; 69 | } 70 | 71 | fool_loader_autoload(controller_name TSRMLS_CC); 72 | 73 | if(zend_hash_find(EG(class_table),controller_name_lower,clen+1,(void**)&ce TSRMLS_CC) == SUCCESS){ 74 | return *ce; 75 | } 76 | 77 | efree(controller_name_lower); 78 | return NULL; 79 | } 80 | /*}}}*/ 81 | 82 | /*{{{ zval* fool_dispatcher_dispatch(zval* dispatcher TSRMLS_DC) 83 | */ 84 | zval* fool_dispatcher_dispatch(zval* dispatcher TSRMLS_DC) 85 | { 86 | zval* response; 87 | zval* request; 88 | zval* view; 89 | 90 | request = fool_request_instance(TSRMLS_C); 91 | if(!request){ 92 | fool_throw_exception(101,"[Error]Can't get the instance of Fool_Request" TSRMLS_CC); 93 | return NULL; 94 | } 95 | zend_update_property(fool_dispatcher_ce,dispatcher,ZEND_STRL(FOOL_DISPATCHER_PROPERTY_NAME_REQUEST),request TSRMLS_CC); 96 | 97 | int parse_method_res = fool_request_parse_method(request TSRMLS_CC); 98 | if(!parse_method_res){ 99 | fool_throw_exception(102,"[Error]Can't parse the variable of GET['method']" TSRMLS_CC); 100 | return NULL; 101 | } 102 | //init Fool_View 103 | view = fool_view_instance(TSRMLS_C); 104 | 105 | zval *controller_name,*controller,*action; 106 | zend_class_entry* ce; 107 | 108 | controller_name = fool_request_get_controller(request TSRMLS_CC); 109 | ce = fool_dispatcher_get_controller(Z_STRVAL_P(controller_name) TSRMLS_CC); 110 | 111 | if(!ce){ 112 | char* msg; 113 | spprintf(&msg,0,"[Error]Can't find the class of condtroller : %s",Z_STRVAL_P(controller_name)); 114 | fool_throw_exception(100,msg TSRMLS_CC); 115 | efree(msg); 116 | return NULL; 117 | } 118 | 119 | MAKE_STD_ZVAL(controller); 120 | //实例化对象 121 | object_init_ex(controller, ce); 122 | 123 | //action handler 124 | fool_controller_dispatch_handler(ce,controller,request,view TSRMLS_CC); 125 | 126 | zval_ptr_dtor(&controller); 127 | return NULL;//response; 128 | } 129 | /*}}}*/ 130 | 131 | /*{{{ public Fool_Application::getInstance(void) 132 | */ 133 | PHP_METHOD(fool_dispatcher,__construct) 134 | { 135 | } 136 | /*}}}*/ 137 | 138 | /*{{{ public Fool_Application::getInstance(void) 139 | */ 140 | PHP_METHOD(fool_dispatcher,getInstance) 141 | { 142 | zval* instance = fool_dispatcher_instance(TSRMLS_C); 143 | 144 | if(instance){ 145 | RETURN_ZVAL(instance,1,0); 146 | } 147 | RETURN_FALSE; 148 | } 149 | /*}}}*/ 150 | 151 | 152 | zend_function_entry fool_dispatcher_methods[] = { 153 | ZEND_ME(fool_dispatcher,__construct,fool_dispatcher_construct_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) 154 | ZEND_ME(fool_dispatcher,getInstance,fool_dispatcher_getinstance_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) 155 | PHP_FE_END /* Must be the last line in qpclass_functions[] */ 156 | }; 157 | 158 | 159 | FOOL_STARTUP_MODULE(dispatcher) 160 | { 161 | zend_class_entry ce; 162 | INIT_CLASS_ENTRY(ce,"Fool_Dispatcher",fool_dispatcher_methods); 163 | 164 | fool_dispatcher_ce = zend_register_internal_class(&ce TSRMLS_CC); 165 | 166 | zend_declare_property_null(fool_dispatcher_ce,ZEND_STRL(FOOL_DISPATCHER_PROPERTY_NAME_INSTANCE),ZEND_ACC_PRIVATE|ZEND_ACC_STATIC TSRMLS_CC); 167 | zend_declare_property_null(fool_dispatcher_ce,ZEND_STRL(FOOL_DISPATCHER_PROPERTY_NAME_REQUEST),ZEND_ACC_PRIVATE TSRMLS_CC); 168 | 169 | return SUCCESS; 170 | } 171 | 172 | 173 | /* 174 | * Local variables: 175 | * tab-width: 4 176 | * c-basic-offset: 4 177 | * End: 178 | * vim600: noet sw=4 ts=4 fdm=marker 179 | * vim<600: noet sw=4 ts=4 180 | */ 181 | -------------------------------------------------------------------------------- /fool_config.c: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #include "php.h" 6 | #include "php_ini.h" 7 | #include "ext/standard/info.h" 8 | #include "Zend/zend_interfaces.h" 9 | #include "php_foolphp.h" 10 | 11 | #include "fool_application.h" 12 | #include "fool_dispatcher.h" 13 | #include "fool_loader.h" 14 | #include "fool_request.h" 15 | #include "fool_controller.h" 16 | #include "fool_object.h" 17 | #include "fool_view.h" 18 | #include "fool_config.h" 19 | #include "fool_exception.h" 20 | 21 | zend_class_entry* fool_config_ce; 22 | 23 | 24 | ZEND_BEGIN_ARG_INFO_EX(fool_config_construct_arginfo, 0, 0, 0) 25 | ZEND_END_ARG_INFO() 26 | 27 | ZEND_BEGIN_ARG_INFO_EX(fool_config_find_arginfo, 0, 0, 1) 28 | ZEND_ARG_INFO(0, class_name) 29 | ZEND_END_ARG_INFO() 30 | 31 | 32 | /*{{{ int fool_config_get_defined_vars(char* config_path,zval* var_list TSRMLS_DC) 33 | */ 34 | int fool_config_get_defined_vars(char* config_path,zval* var_list TSRMLS_DC) 35 | { 36 | HashTable *calling_symbol_table; 37 | //保存当前符号表 38 | if (EG(active_symbol_table)) { 39 | calling_symbol_table = EG(active_symbol_table); 40 | } else { 41 | calling_symbol_table = NULL; 42 | } 43 | 44 | //重置符号表 45 | ALLOC_HASHTABLE(EG(active_symbol_table)); 46 | zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0); 47 | 48 | int res = fool_loader_include(config_path); 49 | 50 | /*遍历active_symbol_table存入var_list*/ 51 | zval **entry; 52 | char *var_name; 53 | long num_key; 54 | uint var_name_len; 55 | HashPosition pos; 56 | 57 | for(zend_hash_internal_pointer_reset_ex(EG(active_symbol_table), &pos); 58 | zend_hash_get_current_data_ex(EG(active_symbol_table), (void **)&entry, &pos) == SUCCESS; 59 | zend_hash_move_forward_ex(EG(active_symbol_table), &pos)) { 60 | 61 | if (zend_hash_get_current_key_ex(EG(active_symbol_table), &var_name, &var_name_len, &num_key, 0, &pos) != HASH_KEY_IS_STRING) { 62 | continue; 63 | } 64 | 65 | ZEND_SET_SYMBOL_WITH_LENGTH(Z_ARRVAL_P(var_list), var_name, var_name_len, 66 | *entry, Z_REFCOUNT_P(*entry) + 1, PZVAL_IS_REF(*entry)); 67 | } 68 | /*end*/ 69 | 70 | if (calling_symbol_table) { 71 | zend_hash_destroy(EG(active_symbol_table)); 72 | FREE_HASHTABLE(EG(active_symbol_table)); 73 | EG(active_symbol_table) = calling_symbol_table; 74 | } 75 | 76 | return 1; 77 | } 78 | /*}}}*/ 79 | 80 | /**{{{ int fool_config_init(TSRMLS_D) 81 | */ 82 | int fool_config_init(TSRMLS_D) 83 | { 84 | zval* instance = NULL; 85 | zval* var_list; 86 | 87 | instance = zend_read_static_property(fool_config_ce,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_INSTANCE),1 TSRMLS_CC); 88 | 89 | if(instance && Z_BVAL_P(instance)){ 90 | return 1; 91 | } 92 | 93 | ZVAL_TRUE(instance); 94 | zend_update_static_property(fool_config_ce,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_INSTANCE),instance TSRMLS_CC); 95 | 96 | if(instance){ 97 | //初始化obj_list 98 | MAKE_STD_ZVAL(var_list); 99 | array_init(var_list); 100 | 101 | char* config_path; 102 | spprintf(&config_path,0,"%s/%s",FOOLPHP_G(config_path),FOOLPHP_G(config_name)); 103 | 104 | fool_config_get_defined_vars(config_path,var_list TSRMLS_CC); 105 | 106 | zend_update_static_property(fool_config_ce,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_VAR),var_list TSRMLS_CC); 107 | 108 | efree(config_path); 109 | } 110 | return 1; 111 | } 112 | /*}}}*/ 113 | 114 | /*{{{ zval* fool_config_get(zval* object,char* class_name,int name_len TSRMLS_DC) 115 | */ 116 | zval* fool_config_get(zval* object,char* class_name,int name_len TSRMLS_DC) 117 | { 118 | zval* obj_list = zend_read_property(fool_config_ce,object,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_VAR),1 TSRMLS_CC); 119 | if(!obj_list){ 120 | return NULL; 121 | } 122 | 123 | zval** _obj; 124 | if(zend_hash_find(Z_ARRVAL_P(obj_list),class_name,name_len+1,(void**)&_obj) == FAILURE){ 125 | return NULL; 126 | } 127 | return *_obj; 128 | } 129 | /*}}}*/ 130 | 131 | /*{{{ public Fool_Config::__construct(void) 132 | */ 133 | PHP_METHOD(fool_config,__construct) 134 | { 135 | } 136 | /*}}}*/ 137 | 138 | /*{{{ public Fool_Config::find(string $class) 139 | */ 140 | PHP_METHOD(fool_config,find) 141 | { 142 | char* var_name; 143 | int var_name_len; 144 | 145 | if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&var_name,&var_name_len) == FAILURE){ 146 | RETURN_FALSE; 147 | } 148 | 149 | zval* config = zend_read_static_property(fool_config_ce,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_VAR),1 TSRMLS_CC); 150 | if(!config){ 151 | RETURN_FALSE; 152 | } 153 | 154 | 155 | zval** value; 156 | if(zend_hash_find(Z_ARRVAL_P(config),var_name,var_name_len+1,(void**)&value) == FAILURE){ 157 | RETURN_FALSE; 158 | } 159 | RETURN_ZVAL(*value,1,0); 160 | } 161 | /*}}}*/ 162 | 163 | 164 | zend_function_entry fool_config_methods[] = { 165 | ZEND_ME(fool_config,__construct,fool_config_construct_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) 166 | ZEND_ME(fool_config,find,fool_config_find_arginfo,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) 167 | PHP_FE_END /* Must be the last line in qpclass_functions[] */ 168 | }; 169 | 170 | 171 | FOOL_STARTUP_MODULE(config) 172 | { 173 | zend_class_entry ce; 174 | INIT_CLASS_ENTRY(ce,"Fool_Config",fool_config_methods); 175 | 176 | fool_config_ce = zend_register_internal_class(&ce TSRMLS_CC); 177 | 178 | zend_declare_property_null(fool_config_ce,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_INSTANCE),ZEND_ACC_PUBLIC|ZEND_ACC_STATIC TSRMLS_CC); 179 | zend_declare_property_null(fool_config_ce,ZEND_STRL(FOOL_CONFIG_PROPERTY_NAME_VAR),ZEND_ACC_PUBLIC|ZEND_ACC_STATIC TSRMLS_CC); 180 | 181 | return SUCCESS; 182 | } 183 | 184 | 185 | /* 186 | * Local variables: 187 | * tab-width: 4 188 | * c-basic-offset: 4 189 | * End: 190 | * vim600: noet sw=4 ts=4 fdm=marker 191 | * vim<600: noet sw=4 ts=4 192 | */ 193 | -------------------------------------------------------------------------------- /tools/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | root=`pwd` 4 | application_path=$root"/src/application" 5 | config_path=$root"/src/config" 6 | web_path=$root"/src/www" 7 | tool_root=$root"/tools" 8 | 9 | 10 | black='\E[0m\c' 11 | red='\E[31m\c' 12 | c_notify='\E[1;36m\c' 13 | 14 | PHP=`command -v php` 15 | if [ -z "${PHP}" ];then 16 | echo "php not found" 17 | exit 1 18 | fi 19 | 20 | 21 | cprint() 22 | { 23 | color=${2:-$red} 24 | echo -e "$color" 25 | echo "$1" 26 | echo -e "$black" 27 | return 28 | } 29 | 30 | build_index() 31 | { 32 | cprint "[4/6]创建入口文件:index.php" $c_notify 33 | cat>"${root}/src/www/index.php"<run(); 40 | INDEX 41 | chmod 755 "${root}/src/www/index.php" 42 | echo "build: ${root}/src/www/index.php -----finish" 43 | } 44 | 45 | build_config() 46 | { 47 | cat>"${config_path}/config.inc.php"<"${application_path}/controllers/DemoController.php"<GetTime(); 65 | 66 | \$this->assign('time',\$now); 67 | \$this->assign('web_title',Fool_Config::find("title")); 68 | \$this->display(); 69 | } 70 | } 71 | EOF 72 | echo "build: ${application_path}/controllers/DemoController.php -----finish" 73 | } 74 | 75 | build_model() 76 | { 77 | cat>"${application_path}/models/DemoModel.php"<"${tool_root}/config.php"<"${application_path}/views/Common/header.tpl.php"<
109 | 110 | 111 | 112 | <?php echo \$web_title;?> 113 | 118 | 119 | HEADER 120 | 121 | cat>"${application_path}/views/Common/footer.tpl.php"<