├── Runtime └── README.md ├── logo.jpg ├── Data ├── user.sql └── phalapi_test.sql ├── Example ├── listapis.png ├── comments.json.png ├── content_api.png ├── default_home.json.png ├── 360截图20170106205511853.jpg ├── qiniu.html ├── uoload_photo.html └── README.md ├── PhalApi ├── Tests │ ├── Config │ │ ├── sys.php │ │ ├── app.php │ │ ├── PhalApi_Config_Yaconf_Test.php │ │ └── dbs.php │ ├── test_file_for_loader.php │ ├── Data │ │ └── Language │ │ │ └── zh_cn │ │ │ └── common.php │ ├── Request │ │ └── Formatter │ │ │ ├── Classes │ │ │ ├── FormatterCallbackMyClass.php │ │ │ └── FormatterCallbackMyClass2.php │ │ │ ├── PhalApi_Request_Formatter_Boolean_Test.php │ │ │ ├── PhalApi_Request_Formatter_Enum.php │ │ │ ├── PhalApi_Request_Formatter_Array_Test.php │ │ │ └── PhalApi_Request_Formatter_Date_Test.php │ ├── Language │ │ └── zh_cn │ │ │ └── common.php │ ├── phpunit.xml │ ├── Crypt │ │ └── RSA │ │ │ ├── PhalApi_Crypt_RSA_MultiPub2Pri_Test.php │ │ │ └── PhalApi_Crypt_RSA_Pri2Pub_Test.php │ ├── PhalApi_CUrl_Test.php │ ├── Cache │ │ ├── PhalApi_Cache_None_Test.php │ │ ├── PhalApi_Cache_APCU_Test.php │ │ ├── PhalApi_Cache_Multi_Test.php │ │ ├── PhalApi_Cache_Memcached_Test.php │ │ └── PhalApi_Cache_File_Test.php │ ├── Helper │ │ ├── PhalApi_Helper_TestRunner_Test.php │ │ ├── PhalApi_Helper_ApiDesc_Test.php │ │ └── PhalApi_Helper_Tracer_Test.php │ ├── Filter │ │ ├── PhalApi_Filter_None_Test.php │ │ └── PhalApi_Filter_SimpleMd5_Test.php │ ├── PhalApi_Config_File_Test.php │ ├── Logger │ │ └── PhalApi_Logger_Explorer_Test.php │ ├── PhalApi_Cookie_Test.php │ ├── PhalApi_ModelProxy_Test.php │ ├── PhalApi_ModelQuery_Test.php │ ├── PhalApi_Loader_Test.php │ ├── Cookie │ │ └── PhalApi_Cookie_Multi_Test.php │ └── PhalApi_Translator_Test.php ├── phalapi-buildcode ├── phalapi-buildsqls ├── phalapi-buildtest ├── PhalApi │ ├── Helper │ │ ├── _Domain.php.tpl │ │ ├── _Model.php.tpl │ │ ├── _Api.php.tpl │ │ └── TestRunner.php │ ├── DB.php │ ├── Exception.php │ ├── Request │ │ ├── Formatter.php │ │ └── Formatter │ │ │ ├── Callback.php │ │ │ ├── Int.php │ │ │ ├── Float.php │ │ │ ├── Boolean.php │ │ │ ├── Array.php │ │ │ ├── Date.php │ │ │ ├── Enum.php │ │ │ ├── Callable.php │ │ │ ├── String.php │ │ │ └── Base.php │ ├── Filter │ │ ├── None.php │ │ └── SimpleMD5.php │ ├── Response │ │ ├── Explorer.php │ │ ├── Json.php │ │ └── JsonP.php │ ├── Cache │ │ ├── None.php │ │ ├── Memcached.php │ │ ├── APCU.php │ │ ├── Multi.php │ │ └── Memcache.php │ ├── Exception │ │ ├── BadRequest.php │ │ └── InternalServerError.php │ ├── Filter.php │ ├── Crypt.php │ ├── functions.php │ ├── Cache.php │ ├── Crypt │ │ ├── RSA │ │ │ ├── Pri2Pub.php │ │ │ ├── Pub2Pri.php │ │ │ ├── KeyGenerator.php │ │ │ ├── MultiPri2Pub.php │ │ │ └── MultiPub2Pri.php │ │ └── MultiMcrypt.php │ ├── Logger │ │ └── Explorer.php │ ├── Config │ │ ├── Yaconf.php │ │ └── File.php │ ├── Config.php │ ├── ModelQuery.php │ ├── Model.php │ ├── Cookie │ │ └── Multi.php │ └── ApiFactory.php ├── NotORM │ └── NotORM │ │ └── Literal.php ├── Language │ └── en │ │ └── common.php └── PhalApi.php ├── Library ├── README.md ├── Task │ ├── Data │ │ ├── task_mq.sql │ │ ├── task_progress.sql │ │ └── phalapi_task_progress.sql │ ├── Progress │ │ ├── Trigger.php │ │ └── Trigger │ │ │ └── Common.php │ ├── Runner │ │ ├── Remote │ │ │ ├── Connector │ │ │ │ └── Http.php │ │ │ └── Connector.php │ │ ├── Local.php │ │ └── Remote.php │ ├── crontab.php │ ├── Config │ │ ├── dbs.php │ │ └── app.php │ ├── Tests │ │ ├── test_env.php │ │ ├── Task_Progress_Test.php │ │ ├── Task_Lite_Test.php │ │ ├── MQ │ │ │ ├── Task_MQ_Redis_Test.php │ │ │ ├── Task_MQ_File_Test.php │ │ │ ├── Task_MQ_Memcached_Test.php │ │ │ ├── Task_MQ_Array_Test.php │ │ │ └── Task_MQ_DB_Test.php │ │ ├── Runner │ │ │ ├── Task_Runner_Remote_Test.php │ │ │ └── Task_Runner_Local_Test.php │ │ └── Task_Runner_Test.php │ ├── MQ │ │ ├── DB.php │ │ ├── File.php │ │ ├── Array.php │ │ ├── Memcached.php │ │ ├── Redis.php │ │ └── KeyValue.php │ ├── MQ.php │ ├── check.php │ ├── Lite.php │ ├── Task │ │ └── Model │ │ │ └── Task │ │ │ ├── TaskMq.php │ │ │ └── TaskProgress.php │ └── Runner.php └── Qiniu │ ├── Config │ └── app.php │ ├── qiniu │ ├── utils.php │ ├── conf.php │ ├── rsf.php │ ├── fop.php │ ├── rs_utils.php │ └── auth_digest.php │ ├── usage │ └── CDN.php │ ├── CDN │ └── Api │ │ └── Qiniu │ │ └── CDN.php │ └── Lite.php ├── upload └── quanmin │ └── image │ └── 2017 │ └── 04 │ └── 02 │ ├── 05444680386578567.jpg │ ├── 05444689974360448.jpg │ └── 05444683517706998494332.jpg ├── Language ├── zh_tw │ └── common.php ├── en │ └── common.php └── zh_cn │ └── common.php ├── qm ├── Domain │ ├── Android.php │ ├── Focus.php │ ├── Content.php │ ├── Comment.php │ ├── Good.php │ └── User.php ├── Model │ ├── Android.php │ └── Focus.php ├── Tests │ ├── test_env.php │ ├── phpunit_user_getbaseinfo.xml │ ├── Model │ │ └── Model_User_Test.php │ ├── phpunit.xml │ ├── Domain │ │ └── Domain_User_Test.php │ └── Api │ │ ├── Api_Default_Test.php │ │ └── Api_User_Test.php ├── ModelProxy │ └── UserBaseInfo.php └── Api │ ├── Android.php │ ├── Default.php │ ├── UploadFile.php │ └── Focus.php ├── .gitignore ├── Public ├── qm │ ├── index.php │ └── checkApiParams.php ├── index.php ├── install │ ├── _footer.php │ ├── _error.php │ ├── _step3.php │ ├── _header.php │ ├── _step1.php │ └── _start.php └── init.php ├── LICENSE.md ├── Config ├── sys.php └── app.php ├── composer.json ├── SDK └── PHP │ └── PhalApiClient │ └── sky.php └── README.md /Runtime/README.md: -------------------------------------------------------------------------------- 1 | Hey guys, logs file here! -------------------------------------------------------------------------------- /logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/logo.jpg -------------------------------------------------------------------------------- /Data/user.sql: -------------------------------------------------------------------------------- 1 | `name` VARCHAR(45) NULL, 2 | `note` VARCHAR(45) NULL, 3 | -------------------------------------------------------------------------------- /Example/listapis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/Example/listapis.png -------------------------------------------------------------------------------- /PhalApi/Tests/Config/sys.php: -------------------------------------------------------------------------------- 1 | false, 5 | ); 6 | -------------------------------------------------------------------------------- /Example/comments.json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/Example/comments.json.png -------------------------------------------------------------------------------- /Example/content_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/Example/content_api.png -------------------------------------------------------------------------------- /PhalApi/Tests/test_file_for_loader.php: -------------------------------------------------------------------------------- 1 | 'Hello PhpUnit'); 3 | -------------------------------------------------------------------------------- /Library/README.md: -------------------------------------------------------------------------------- 1 | ##扩展类库 2 | 3 | 请查看: 4 | 5 | ``` 6 | http://git.oschina.net/dogstar/PhalApi-Library 7 | ``` -------------------------------------------------------------------------------- /Example/default_home.json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/Example/default_home.json.png -------------------------------------------------------------------------------- /Example/360截图20170106205511853.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/Example/360截图20170106205511853.jpg -------------------------------------------------------------------------------- /PhalApi/Tests/Data/Language/zh_cn/common.php: -------------------------------------------------------------------------------- 1 | 'this is a good way', 5 | ); 6 | -------------------------------------------------------------------------------- /upload/quanmin/image/2017/04/02/05444680386578567.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/upload/quanmin/image/2017/04/02/05444680386578567.jpg -------------------------------------------------------------------------------- /upload/quanmin/image/2017/04/02/05444689974360448.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/upload/quanmin/image/2017/04/02/05444689974360448.jpg -------------------------------------------------------------------------------- /Language/zh_tw/common.php: -------------------------------------------------------------------------------- 1 | '{name}您好,歡迎使用PhalApi!', 5 | 'user not exists' => '用戶不存在', 6 | ); 7 | -------------------------------------------------------------------------------- /Library/Task/Data/task_mq.sql: -------------------------------------------------------------------------------- 1 | `service` varchar(200) DEFAULT '' COMMENT '接口服务名称', 2 | `params` text COMMENT 'json格式的参数', 3 | `create_time` int(11) DEFAULT '0', 4 | -------------------------------------------------------------------------------- /upload/quanmin/image/2017/04/02/05444683517706998494332.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao91/PhalApi-TianGou/HEAD/upload/quanmin/image/2017/04/02/05444683517706998494332.jpg -------------------------------------------------------------------------------- /Language/en/common.php: -------------------------------------------------------------------------------- 1 | 'Hello {name}, Welcome to use PhalApi!', 5 | 'user not exists' => 'user not exists', 6 | ); 7 | -------------------------------------------------------------------------------- /PhalApi/Tests/Request/Formatter/Classes/FormatterCallbackMyClass.php: -------------------------------------------------------------------------------- 1 | getApkInfo(); 9 | 10 | return $apkInfo; 11 | } 12 | } -------------------------------------------------------------------------------- /PhalApi/phalapi-buildcode: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | loader->addDirs('qm'); 10 | 11 | /** ---------------- 响应接口请求 ---------------- **/ 12 | 13 | $api = new PhalApi(); 14 | $rs = $api->response(); 15 | $rs->output(); 16 | 17 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ##协议许可的权利 - GPL协议 2 | 3 | PhalApi官方网站为 http://www.phalapi.net,依法独立拥有 PhalApi 及官网发布的PhalApi衍生产品著作权。 4 | PhalApi及其衍生产品著作权受到法律和国际公约保护。使用者需仔细阅读本协议,在理解、同意、并遵守本协 5 | 议的全部条款后,方可开始使用 PhalApi及其衍生 软件。 6 | 7 | 本授权协议适用于 http://www.phalapi.net 发布的所有应用程序,PhalApi官方网站拥有对本授权协议的最终 8 | 解释权。 9 | 10 | PhalApi是一个PHP轻量级开源接口框架,并承诺永久免费!请放心使用! -------------------------------------------------------------------------------- /Library/Task/Progress/Trigger.php: -------------------------------------------------------------------------------- 1 | 20150520 6 | */ 7 | 8 | interface Task_Progress_Trigger { 9 | 10 | /** 11 | * 进程的具体操作 12 | * @param string $params 对应数据库表task_progress.fire_params字段 13 | */ 14 | public function fire($params); 15 | } 16 | -------------------------------------------------------------------------------- /Language/zh_cn/common.php: -------------------------------------------------------------------------------- 1 | 2015-02-09 9 | */ 10 | 11 | return array( 12 | 'Hi {name}, welcome to use PhalApi!' => '{name}您好,欢迎使用PhalApi!', 13 | 'user not exists' => '用户不存在', 14 | ); 15 | -------------------------------------------------------------------------------- /Library/Task/Runner/Remote/Connector/Http.php: -------------------------------------------------------------------------------- 1 | get('curl', 'PhalApi_CUrl'); 7 | 8 | return $curl->post($url, $data, $timeoutMs); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /qm/Model/Android.php: -------------------------------------------------------------------------------- 1 | notorm->android; 8 | $apkVersionCode = $apkInfoORM->max('version_code'); 9 | $apkInfo = $apkInfoORM->where('version_code', $apkVersionCode); 10 | 11 | return $apkInfo; 12 | } 13 | } -------------------------------------------------------------------------------- /Library/Qiniu/Config/app.php: -------------------------------------------------------------------------------- 1 | array( 8 | //统一的key 9 | 'accessKey' => '*****', 10 | 'secretKey' => '****', 11 | //自定义配置的空间 12 | 'space_bucket' => '自定义配置的空间', 13 | 'space_host' => 'http://XXXXX.qiniudn.com', 14 | ), 15 | ); 16 | -------------------------------------------------------------------------------- /Example/qiniu.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |
9 | 10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /PhalApi/Tests/Language/zh_cn/common.php: -------------------------------------------------------------------------------- 1 | '{name}您好,欢迎使用PhalApi!', 12 | 'user not exists' => '用户不存在', 13 | '{0} I love you' => '{0} 我爱你', 14 | '{0} I love you because {1}' => '{0} 我爱你因为{1}', 15 | ); 16 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/DB.php: -------------------------------------------------------------------------------- 1 | 2015-02-09 11 | */ 12 | interface PhalApi_DB{ 13 | 14 | public function connect(); 15 | 16 | public function disconnect(); 17 | } 18 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Exception.php: -------------------------------------------------------------------------------- 1 | 2014-10-02 11 | */ 12 | 13 | class PhalApi_Exception extends Exception { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | interface PhalApi_Request_Formatter { 12 | 13 | public function parse($value, $rule); 14 | } 15 | -------------------------------------------------------------------------------- /Library/Qiniu/qiniu/utils.php: -------------------------------------------------------------------------------- 1 | false, 11 | 12 | /** 13 | * MC缓存服务器参考配置 14 | */ 15 | 'mc' => array( 16 | 'host' => '127.0.0.1', 17 | 'port' => 11211, 18 | ), 19 | 20 | /** 21 | * 加密 22 | */ 23 | 'crypt' => array( 24 | 'mcrypt_iv' => '12345678', //8位 25 | ), 26 | ); 27 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Filter/None.php: -------------------------------------------------------------------------------- 1 | 2015-10-23 9 | */ 10 | 11 | class PhalApi_Filter_None implements PhalApi_Filter { 12 | 13 | public function check() { 14 | // nothing here ... 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /qm/Tests/test_env.php: -------------------------------------------------------------------------------- 1 | loader->addDirs('Demo'); 12 | 13 | //日记纪录 - Explorer 14 | DI()->logger = new PhalApi_Logger_Explorer( 15 | PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR); 16 | 17 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Response/Explorer.php: -------------------------------------------------------------------------------- 1 | 2015-02-09 9 | */ 10 | 11 | class PhalApi_Response_Explorer extends PhalApi_Response { 12 | 13 | protected function formatResult($result) { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Public/index.php: -------------------------------------------------------------------------------- 1 | loader->addDirs('qm'); 10 | 11 | // 云存储 12 | DI()->ucloud = new UCloud_Lite(); 13 | 14 | /** ---------------- 响应接口请求 ---------------- **/ 15 | 16 | /** 17 | * 全部采用post方式请求数据 18 | */ 19 | //DI()->request = new PhalApi_Request($_POST); 20 | 21 | $api = new PhalApi(); 22 | $rs = $api->response(); 23 | $rs->output(); 24 | 25 | -------------------------------------------------------------------------------- /Library/Task/crontab.php: -------------------------------------------------------------------------------- 1 | loader->addDirs(array('Demo', 'Library', 'Library/Task/Task')); 6 | 7 | try { 8 | $progress = new Task_Progress(); 9 | $progress->run(); 10 | } catch (Exception $ex) { 11 | echo $ex->getMessage(); 12 | echo "\n\n"; 13 | echo $ex->getTraceAsString(); 14 | // notify ... 15 | } 16 | -------------------------------------------------------------------------------- /qm/ModelProxy/UserBaseInfo.php: -------------------------------------------------------------------------------- 1 | 2015-02-22 4 | */ 5 | 6 | class ModelProxy_UserBaseInfo extends PhalApi_ModelProxy { 7 | 8 | protected function doGetData($query) { 9 | $model = new Model_User(); 10 | 11 | return $model->getByUserId($query->id); 12 | } 13 | 14 | protected function getKey($query) { 15 | return 'userbaseinfo_' . $query->id; 16 | } 17 | 18 | protected function getExpire($query) { 19 | return 600; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Library/Qiniu/qiniu/conf.php: -------------------------------------------------------------------------------- 1 | '; 18 | $QINIU_SECRET_KEY = ''; 19 | 20 | -------------------------------------------------------------------------------- /Library/Task/Config/dbs.php: -------------------------------------------------------------------------------- 1 | array( 6 | 7 | //请将以下配置拷贝到 ./Config/dbs.php 文件对应的位置中,未配置的表将使用默认路由 8 | 9 | //10张表,可根据需要,自行调整表前缀、主键名和路由 10 | 'task_mq' => array( 11 | 'prefix' => 'phalapi_', 12 | 'key' => 'id', 13 | 'map' => array( 14 | array('db' => 'db_demo'), 15 | array('start' => 0, 'end' => 9, 'db' => 'db_demo'), 16 | ), 17 | ), 18 | ) 19 | ); 20 | 21 | 22 | -------------------------------------------------------------------------------- /Library/Task/Data/task_progress.sql: -------------------------------------------------------------------------------- 1 | `title` varchar(200) DEFAULT '' COMMENT '任务标题', 2 | `trigger_class` varchar(50) DEFAULT '' COMMENT '触发器类名', 3 | `fire_params` varchar(255) DEFAULT '' COMMENT '需要传递的参数,格式自定', 4 | `interval_time` int(11) DEFAULT '0' COMMENT '执行间隔,单位:秒', 5 | `enable` tinyint(1) DEFAULT '1' COMMENT '是否启动,1启动,0禁止', 6 | `result` varchar(255) DEFAULT '' COMMENT '运行的结果,以json格式保存', 7 | `state` tinyint(1) DEFAULT '0' COMMENT '进程状态,0空闲,1运行中,-1异常退出', 8 | `last_fire_time` int(11) DEFAULT '0' COMMENT '上一次运行时间', 9 | -------------------------------------------------------------------------------- /Example/uoload_photo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 测试HTML 6 | 7 | 8 |
9 |

10 | 用户id 11 |

12 |

13 | 14 |

15 |

16 | 17 |

18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /Library/Task/Tests/test_env.php: -------------------------------------------------------------------------------- 1 | loader->addDirs('Demo'); 8 | DI()->loader->addDirs('Library'); 9 | DI()->loader->addDirs('./Library/Task/Task'); 10 | 11 | DI()->logger = new PhalApi_Logger_Explorer( 12 | PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR); 13 | 14 | SL('en'); 15 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Callback.php: -------------------------------------------------------------------------------- 1 | 2017-04-19 12 | */ 13 | 14 | 15 | class PhalApi_Request_Formatter_Callback extends PhalApi_Request_Formatter_Callable { 16 | } 17 | -------------------------------------------------------------------------------- /Library/Task/MQ/DB.php: -------------------------------------------------------------------------------- 1 | 20150516 8 | */ 9 | 10 | class Task_MQ_DB implements Task_MQ { 11 | 12 | public function add($service, $params = array()) { 13 | $model = new Model_Task_TaskMq(); 14 | return $model->add($service, $params); 15 | } 16 | 17 | public function pop($service, $num = 1) { 18 | $model = new Model_Task_TaskMq(); 19 | return $model->pop($service, $num); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Library/Task/MQ.php: -------------------------------------------------------------------------------- 1 | 20150516 8 | */ 9 | 10 | interface Task_MQ { 11 | 12 | /** 13 | * 单个添加 14 | * @param string $service 接口服务名称,如:Default.Index 15 | * @param array $params 接口服务参数 16 | */ 17 | public function add($service, $params = array()); 18 | 19 | /** 20 | * 批量弹出 21 | * @param string $service 需要获取的接口服务名称 22 | * @param int $num 弹出的个数 23 | */ 24 | public function pop($service, $num = 1); 25 | } 26 | -------------------------------------------------------------------------------- /Public/install/_footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Example/README.md: -------------------------------------------------------------------------------- 1 | ##API接口数据来源## 2 | 3 | 数据来源:[易源API接口](https://www.showapi.com) 4 | 5 | 类型1: 6 | 7 | 文本笑话:[来福岛笑话接口](https://www.showapi.com/api/lookPoint/107) 8 | 9 | 类型2: 10 | 11 | 内涵图片:[来福岛搞笑图片接口](https://www.showapi.com/api/lookPoint/107) 12 | 13 | 类型3: 14 | 15 | 美女图片:[美图大全接口](https://www.showapi.com/api/lookPoint/852) 16 | 17 | 类型4: 18 | 19 | 故事:[鬼故事接口](https://www.showapi.com/api/lookPoint/955/1) 20 | 21 | 类型5: 22 | 23 | 漫画:[憨憨漫画接口](https://www.showapi.com/api/lookPoint/978/1) 24 | 25 | 类型6: 26 | 27 | 视频:[百思不得姐查询接口](https://www.showapi.com/api/lookPoint/255) -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cache/None.php: -------------------------------------------------------------------------------- 1 | 2015-02-04 9 | */ 10 | 11 | class PhalApi_Cache_None implements PhalApi_Cache { 12 | 13 | public function set($key, $value, $expire = 600) { 14 | } 15 | 16 | public function get($key) { 17 | return NULL; 18 | } 19 | 20 | public function delete($key) { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /PhalApi/Tests/Config/app.php: -------------------------------------------------------------------------------- 1 | array( 5 | 'from' => array('name' => 'from', 'default' => 'phpunit'), 6 | ), 7 | 8 | /** 9 | * 接口服务白名单,格式:接口服务类名.接口服务方法名 10 | * 11 | * 示例: 12 | * - *.* 通配,全部接口服务,慎用! 13 | * - Default.* Api_Default接口类的全部方法 14 | * - *.Index 全部接口类的Index方法 15 | * - Default.Index 指定某个接口服务,即Api_Default::Index() 16 | */ 17 | 'service_whitelist' => array( 18 | '*.Index', 19 | 'ServiceWhitelist.PoPo', 20 | ), 21 | ); 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phalapi/phalapi", 3 | "description": "A light-weight framework focus on how to develop API faster and simple.", 4 | "keywords": ["api"], 5 | "homepage": "http://www.phalapi.net", 6 | "license" : "GPL", 7 | "authors": [ 8 | { 9 | "name": "Dogstar Huang", 10 | "email": "chanzonghuang@gmail.com", 11 | "homepage" : "http://my.oschina.net/dogstar", 12 | "role": "Developer" 13 | } 14 | ], 15 | "require": { 16 | "php": ">=5.3.3", 17 | "another-vendor/package": "1.2.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /PhalApi/NotORM/NotORM/Literal.php: -------------------------------------------------------------------------------- 1 | value = $value; 18 | $this->parameters = func_get_args(); 19 | array_shift($this->parameters); 20 | } 21 | 22 | /** Get literal value 23 | * @return string 24 | */ 25 | function __toString() { 26 | return $this->value; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Exception/BadRequest.php: -------------------------------------------------------------------------------- 1 | 2015-02-05 11 | */ 12 | 13 | class PhalApi_Exception_BadRequest extends PhalApi_Exception{ 14 | 15 | public function __construct($message, $code = 0) { 16 | parent::__construct( 17 | T('Bad Request: {message}', array('message' => $message)), 400 + $code 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Response/Json.php: -------------------------------------------------------------------------------- 1 | 2015-02-09 9 | */ 10 | 11 | class PhalApi_Response_Json extends PhalApi_Response { 12 | 13 | public function __construct() { 14 | $this->addHeaders('Content-Type', 'application/json;charset=utf-8'); 15 | } 16 | 17 | protected function formatResult($result) { 18 | return json_encode($result); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Exception/InternalServerError.php: -------------------------------------------------------------------------------- 1 | 2015-02-05 9 | */ 10 | 11 | class PhalApi_Exception_InternalServerError extends PhalApi_Exception { 12 | 13 | public function __construct($message, $code = 0) { 14 | parent::__construct( 15 | T('Interal Server Error: {message}', array('message' => $message)), 500 + $code 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Public/qm/checkApiParams.php: -------------------------------------------------------------------------------- 1 | loader->addDirs('qm'); 12 | 13 | /** 14 | * 扩展类库 15 | * 16 | * TODO: 请根据需要,添加需要显示的扩展路径,即./Api目录的父路径 17 | */ 18 | $libraryPaths = array( 19 | 'Library/User/User', // User扩展 20 | 'Library/Auth/Auth', // Auth扩展 21 | ); 22 | 23 | foreach ($libraryPaths as $aPath) { 24 | $toAddDir = str_replace('/', DIRECTORY_SEPARATOR, $aPath); 25 | DI()->loader->addDirs($toAddDir); 26 | } 27 | 28 | $apiDesc = new PhalApi_Helper_ApiDesc(); 29 | $apiDesc->render(); 30 | 31 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Filter.php: -------------------------------------------------------------------------------- 1 | 实现和使用示例:
8 | ``` 9 | * class My_Filter implements PhalApi_Filter { 10 | * 11 | * public function check() { 12 | * //TODO 13 | * } 14 | * } 15 | * 16 | * //$ vim ./Public/init.php 17 | * //注册签名验证服务 18 | * DI()->filter = 'Common_SignFilter'; 19 | ``` 20 | * 21 | * @package PhalApi\Filter 22 | * @license http://www.phalapi.net/license GPL 协议 23 | * @link http://www.phalapi.net/ 24 | * @author dogstar 2014-10-25 25 | */ 26 | 27 | interface PhalApi_Filter { 28 | 29 | public function check(); 30 | } 31 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Helper/_Api.php.tpl: -------------------------------------------------------------------------------- 1 | array( 12 | ), 13 | ); 14 | } 15 | 16 | /** 17 | * go接口 18 | * @desc go接口描述 19 | * @return int code 状态码,0表示成功,非0表示失败 20 | * @return string msg 状态提示 21 | */ 22 | public function go() { 23 | $rs = array('code' => 0, 'msg' => ''); 24 | 25 | // TODO 26 | $domain = new Domain_{%API_NAME%}(); 27 | $domain->go(); 28 | 29 | return $rs; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Library/Task/Progress/Trigger/Common.php: -------------------------------------------------------------------------------- 1 | 20150520 6 | */ 7 | 8 | class Task_Progress_Trigger_Common implements Task_Progress_Trigger { 9 | 10 | public function fire($params) { 11 | $paramsArr = explode('&', $params); 12 | 13 | $service = !empty($paramsArr[0]) ? trim($paramsArr[0]) : ''; 14 | $mqClass = !empty($paramsArr[1]) ? trim($paramsArr[1]) : 'Task_MQ_Redis'; 15 | $runnerClass = !empty($paramsArr[2]) ? trim($paramsArr[2]) : 'Task_Runner_Local'; 16 | 17 | $mq = new $mqClass(); 18 | $runner = new $runnerClass($mq); 19 | 20 | return $runner->go($service); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Library/Task/Data/phalapi_task_progress.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `phalapi_task_progress` ( 2 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 3 | `title` varchar(200) DEFAULT '' COMMENT '任务标题', 4 | `trigger_class` varchar(50) DEFAULT '' COMMENT '触发器类名', 5 | `fire_params` varchar(255) DEFAULT '' COMMENT '需要传递的参数,格式自定', 6 | `interval_time` int(11) DEFAULT '0' COMMENT '执行间隔,单位:秒', 7 | `enable` tinyint(1) DEFAULT '1' COMMENT '是否启动,1启动,0禁止', 8 | `result` varchar(255) DEFAULT '' COMMENT '运行的结果,以json格式保存', 9 | `state` tinyint(1) DEFAULT '0' COMMENT '进程状态,0空闲,1运行中,-1异常退出', 10 | `last_fire_time` int(11) DEFAULT '0' COMMENT '上一次运行时间', 11 | PRIMARY KEY (`id`) 12 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 13 | 14 | -------------------------------------------------------------------------------- /qm/Domain/Focus.php: -------------------------------------------------------------------------------- 1 | addFocus($user_id, $uid); 15 | return $res; 16 | } 17 | 18 | public function cancelFocus($focus_id) 19 | { 20 | $focus = new Model_Focus(); 21 | $res = $focus->cancelFocus($focus_id); 22 | return $res; 23 | } 24 | 25 | public function readFocus($user_id, $uid) 26 | { 27 | $focus = new Model_Focus(); 28 | $res = $focus->readFocus($user_id, $uid); 29 | return $res; 30 | } 31 | } -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt.php: -------------------------------------------------------------------------------- 1 | 2014-12-10 9 | */ 10 | 11 | interface PhalApi_Crypt { 12 | 13 | /** 14 | * 对称加密 15 | * 16 | * @param mixed $data 等加密的数据 17 | * @param string $key 加密的key 18 | * @return mixed 加密后的数据 19 | */ 20 | public function encrypt($data, $key); 21 | 22 | /** 23 | * 对称解密 24 | * 25 | * @see PhalApi_Crypt::encrypt() 26 | * @param mixed $data 对称加密后的内容 27 | * @param string $key 加密的key 28 | * @return mixed 解密后的数据 29 | */ 30 | public function decrypt($data, $key); 31 | } 32 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Int.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | class PhalApi_Request_Formatter_Int extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 12 | 13 | /** 14 | * 对整型进行格式化 15 | * 16 | * @param mixed $value 变量值 17 | * @param array $rule array('min' => '最小值', 'max' => '最大值') 18 | * @return int/string 格式化后的变量 19 | * 20 | */ 21 | public function parse($value, $rule) { 22 | return intval($this->filterByRange(intval($value), $rule)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /PhalApi/Tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ./ 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/functions.php: -------------------------------------------------------------------------------- 1 | 2014-12-17 8 | */ 9 | 10 | /** 11 | * 获取DI 12 | * 相当于PhalApi_DI::one() 13 | * @return PhalApi_DI 14 | */ 15 | function DI() { 16 | return PhalApi_DI::one(); 17 | } 18 | 19 | /** 20 | * 设定语言,SL为setLanguage的简写 21 | * @param string $language 翻译包的目录名 22 | */ 23 | function SL($language) { 24 | PhalApi_Translator::setLanguage($language); 25 | } 26 | 27 | /** 28 | * 快速翻译 29 | * @param string $msg 待翻译的内容 30 | * @param array $params 动态参数 31 | */ 32 | function T($msg, $params = array()) { 33 | return PhalApi_Translator::get($msg, $params); 34 | } 35 | -------------------------------------------------------------------------------- /Library/Task/MQ/File.php: -------------------------------------------------------------------------------- 1 | 20150516 8 | */ 9 | 10 | class Task_MQ_File extends Task_MQ_KeyValue { 11 | 12 | public function __construct(PhalApi_Cache_File $fileCache = NULL) { 13 | if ($fileCache === NULL) { 14 | $config = DI()->config->get('app.Task.mq.file'); 15 | if (!isset($config['path'])) { 16 | $config['path'] = API_ROOT . '/Runtime'; 17 | } 18 | if (!isset($config['prefix'])) { 19 | $config['prefix'] = 'phalapi_task'; 20 | } 21 | 22 | $fileCache = new PhalApi_Cache_File($config); 23 | } 24 | 25 | parent::__construct($fileCache); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cache/Memcached.php: -------------------------------------------------------------------------------- 1 | 2014-11-14 11 | */ 12 | 13 | class PhalApi_Cache_Memcached extends PhalApi_Cache_Memcache { 14 | 15 | /** 16 | * 注意参数的微妙区别 17 | */ 18 | public function set($key, $value, $expire = 600) { 19 | $this->memcache->set($this->formatKey($key), @serialize($value), $expire); 20 | } 21 | 22 | /** 23 | * 返回更高版本的MC实例 24 | * @return Memcached 25 | */ 26 | protected function createMemcache() { 27 | return new Memcached(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Float.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | class PhalApi_Request_Formatter_Float extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 12 | 13 | /** 14 | * 对浮点型进行格式化 15 | * 16 | * @param mixed $value 变量值 17 | * @param array $rule array('min' => '最小值', 'max' => '最大值') 18 | * @return float/string 格式化后的变量 19 | * 20 | */ 21 | public function parse($value, $rule) { 22 | return floatval($this->filterByRange(floatval($value), $rule)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Library/Task/MQ/Array.php: -------------------------------------------------------------------------------- 1 | 20150516 9 | */ 10 | 11 | class Task_MQ_Array implements Task_MQ { 12 | 13 | protected $list = array(); 14 | 15 | public function add($service, $params = array()) { 16 | if (!isset($this->list[$service])) { 17 | $this->list[$service] = array(); 18 | } 19 | 20 | $this->list[$service][] = $params; 21 | 22 | return TRUE; 23 | } 24 | 25 | public function pop($service, $num = 1) { 26 | if (empty($this->list[$service])) { 27 | return array(); 28 | } 29 | 30 | $rs = array_splice($this->list[$service], 0, $num); 31 | 32 | return $rs; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Library/Task/check.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | loader->addDirs('Demo'); 7 | 8 | if ($argc < 2) { 9 | echo "Usage: $argv[0] \n\n"; 10 | exit(1); 11 | } 12 | 13 | $service = trim($argv[1]); 14 | 15 | echo "Input params(json):\n"; 16 | $params = trim(fgets(STDIN)); 17 | 18 | $params = json_decode($params, true); 19 | if (is_array($params)) { 20 | $params = array(); 21 | } 22 | 23 | $mq = new Task_MQ_Array(); 24 | $taskLite = new Task_Lite($mq); 25 | 26 | $taskLite->add($service, $params); 27 | 28 | $runner = new Task_Runner_Local($mq); 29 | $rs = $runnter->go($service); 30 | 31 | echo "\nDone:\n", json_encode($rs), "\n\n"; 32 | 33 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cache.php: -------------------------------------------------------------------------------- 1 | 2015-02-04 9 | */ 10 | 11 | interface PhalApi_Cache { 12 | 13 | /** 14 | * 设置缓存 15 | * 16 | * @param string $key 缓存key 17 | * @param mixed $value 缓存的内容 18 | * @param int $expire 缓存有效时间,单位秒,非时间戳 19 | */ 20 | public function set($key, $value, $expire = 600); 21 | 22 | /** 23 | * 读取缓存 24 | * 25 | * @param string $key 缓存key 26 | * @return mixed 失败情况下返回NULL 27 | */ 28 | public function get($key); 29 | 30 | /** 31 | * 删除缓存 32 | * 33 | * @param string $key 34 | */ 35 | public function delete($key); 36 | } 37 | -------------------------------------------------------------------------------- /qm/Domain/Content.php: -------------------------------------------------------------------------------- 1 | getContent($content_type); 8 | return $res; 9 | } 10 | 11 | public function deleteContent($content_id) { 12 | $model = new Model_Content(); 13 | $res = $model->deleteContent($content_id); 14 | return $res; 15 | } 16 | 17 | public function getMore($content_type, $current_count) { 18 | $model = new Model_Content(); 19 | $res = $model->getMore($content_type, $current_count); 20 | return $res; 21 | } 22 | 23 | public function addTxtContent($user_id, $content_detail, $content_title, $source_url) { 24 | $model = new Model_Content(); 25 | $res = $model->addTxtContent($user_id, $content_detail, $content_title, $source_url); 26 | return $res; 27 | } 28 | } -------------------------------------------------------------------------------- /qm/Api/Android.php: -------------------------------------------------------------------------------- 1 | array(), 18 | ); 19 | } 20 | 21 | /** 22 | * 获取Android端的apk信息 23 | * @desc 用于获取Android端apk信息 24 | * @return string apk_id 版本id 25 | * @return string version_code 版本号 26 | * @return string version_name 版本名 27 | * @return string download_url 下载地址 28 | * @return string version_desc 版本描述 29 | * 30 | * http://localhost/quanmin/Public/?service=Android.GetApkInfo 31 | * 32 | */ 33 | public function getApkInfo() 34 | { 35 | $domain = new Domain_Android(); 36 | $apkInfo = $domain->getApkInfo(); 37 | 38 | return $apkInfo; 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /qm/Tests/phpunit_user_getbaseinfo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ./Api/Api_User_Test.php 21 | ./Domain/Domain_User_Test.php 22 | ./Model/Model_User_Test.php 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Library/Task/Config/app.php: -------------------------------------------------------------------------------- 1 | array( 11 | //MQ队列设置,可根据使用需要配置 12 | 'mq' => array( 13 | 'file' => array( 14 | 'path' => API_ROOT . '/Runtime', 15 | 'prefix' => 'phalapi_task', 16 | ), 17 | 'redis' => array( 18 | 'host' => '127.0.0.1', 19 | 'port' => 6379, 20 | 'prefix' => 'phalapi_task', 21 | 'auth' => '', 22 | ), 23 | ), 24 | 25 | //Runner设置,如果使用远程调度方式,请加此配置 26 | 'runner' => array( 27 | 'remote' => array( 28 | 'host' => 'http://library.phalapi.net/qm/', 29 | 'timeoutMS' => 3000, 30 | ), 31 | ), 32 | ), 33 | ); 34 | -------------------------------------------------------------------------------- /Library/Task/Tests/Task_Progress_Test.php: -------------------------------------------------------------------------------- 1 | taskProgress = new Task_Progress(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testRun 34 | */ 35 | public function testRun() 36 | { 37 | $rs = $this->taskProgress->run(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /qm/Domain/Comment.php: -------------------------------------------------------------------------------- 1 | getHotAndNewComment($content_id, $user_id); 8 | return $res; 9 | } 10 | 11 | public function addComment($content_id, $comment_detail, $from_uid, $to_uid) { 12 | $model = new Model_Comment(); 13 | $res = $model->addComment($content_id, $comment_detail, $from_uid, $to_uid); 14 | return $res; 15 | } 16 | 17 | public function updateCommentGoodCount($content_id) { 18 | $model = new Model_Comment(); 19 | $res = $model->updateCommentGoodCount($content_id); 20 | return $res; 21 | } 22 | 23 | public function getMoreNewComment($content_id, $create_time) { 24 | $model = new Model_Comment(); 25 | $res = $model->getMoreNewComment($content_id, $create_time); 26 | return $res; 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /Public/install/_error.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 | 7 | 错误提示 8 |
9 |
10 |

安装遇到问题

11 |

12 |
13 |
14 | 我知道了 15 | 16 |
17 |
18 |
19 | 20 | -------------------------------------------------------------------------------- /Library/Task/Runner/Local.php: -------------------------------------------------------------------------------- 1 | 20150516 9 | */ 10 | 11 | class Task_Runner_Local extends Task_Runner { 12 | 13 | protected function youGo($service, $params) { 14 | $params['service'] = $service; 15 | 16 | DI()->request = new PhalApi_Request($params); 17 | DI()->response = new PhalApi_Response_Json(); 18 | 19 | $phalapi = new PhalApi(); 20 | $rs = $phalapi->response(); 21 | $apiRs = $rs->getResult(); 22 | 23 | if ($apiRs['ret'] != 200) { 24 | DI()->logger->debug('task local go fail', 25 | array('servcie' => $service, 'params' => $params, 'rs' => $apiRs)); 26 | 27 | return FALSE; 28 | } 29 | 30 | return TRUE; 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt/RSA/Pri2Pub.php: -------------------------------------------------------------------------------- 1 | 2015-03-14 11 | */ 12 | 13 | class PhalApi_Crypt_RSA_Pri2Pub implements PhalApi_Crypt { 14 | 15 | public function encrypt($data, $prikey) { 16 | $rs = ''; 17 | 18 | if (@openssl_private_encrypt($data, $rs, $prikey) === FALSE) { 19 | return NULL; 20 | } 21 | 22 | return $rs; 23 | } 24 | 25 | public function decrypt($data, $pubkey) { 26 | $rs = ''; 27 | 28 | if (@openssl_public_decrypt($data, $rs, $pubkey) === FALSE) { 29 | return NULL; 30 | } 31 | 32 | return $rs; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Logger/Explorer.php: -------------------------------------------------------------------------------- 1 | 2015-02-09 11 | */ 12 | 13 | class PhalApi_Logger_Explorer extends PhalApi_Logger { 14 | 15 | public function log($type, $msg, $data) { 16 | $msgArr = array(); 17 | $msgArr[] = date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']); 18 | $msgArr[] = strtoupper($type); 19 | $msgArr[] = str_replace(PHP_EOL, '\n', $msg); 20 | if ($data !== NULL) { 21 | $msgArr[] = is_array($data) ? json_encode($data) : $data; 22 | } 23 | 24 | $content = implode('|', $msgArr) . PHP_EOL; 25 | 26 | echo "\n", $content, "\n"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt/RSA/Pub2Pri.php: -------------------------------------------------------------------------------- 1 | 2015-03-15 11 | */ 12 | 13 | class PhalApi_Crypt_RSA_Pub2Pri implements PhalApi_Crypt { 14 | 15 | public function encrypt($data, $pubkey) { 16 | $rs = ''; 17 | 18 | if (@openssl_public_encrypt($data, $rs, $pubkey) === FALSE) { 19 | return NULL; 20 | } 21 | 22 | return $rs; 23 | } 24 | 25 | public function decrypt($data, $prikey) { 26 | $rs = ''; 27 | 28 | if (@openssl_private_decrypt($data, $rs, $prikey) === FALSE) { 29 | return NULL; 30 | } 31 | 32 | return $rs; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /PhalApi/Tests/Crypt/RSA/PhalApi_Crypt_RSA_MultiPub2Pri_Test.php: -------------------------------------------------------------------------------- 1 | privkey = $keyG->getPubKey(); 22 | $this->pubkey = $keyG->getPriKey(); 23 | 24 | $this->phalApiCryptRSAMultiPri2Pub = new PhalApi_Crypt_RSA_MultiPub2Pri(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt/RSA/KeyGenerator.php: -------------------------------------------------------------------------------- 1 | 2015-03-15 11 | */ 12 | 13 | class PhalApi_Crypt_RSA_KeyGenerator { 14 | 15 | protected $privkey; 16 | 17 | protected $pubkey; 18 | 19 | public function __construct() { 20 | $res = openssl_pkey_new(); 21 | openssl_pkey_export($res, $privkey); 22 | $this->privkey = $privkey; 23 | 24 | $pubkey = openssl_pkey_get_details($res); 25 | $this->pubkey = $pubkey['key']; 26 | } 27 | 28 | public function getPriKey() { 29 | return $this->privkey; 30 | } 31 | 32 | public function getPubKey() { 33 | return $this->pubkey; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt/RSA/MultiPri2Pub.php: -------------------------------------------------------------------------------- 1 | 2015-03-14 11 | */ 12 | 13 | class PhalApi_Crypt_RSA_MultiPri2Pub extends PhalApi_Crypt_RSA_MultiBase { 14 | 15 | protected $pri2pub; 16 | 17 | public function __construct() { 18 | $this->pri2pub = new PhalApi_Crypt_RSA_Pri2Pub(); 19 | 20 | parent::__construct(); 21 | } 22 | 23 | protected function doEncrypt($toCryptPie, $prikey) { 24 | return $this->pri2pub->encrypt($toCryptPie, $prikey); 25 | } 26 | 27 | protected function doDecrypt($encryptPie, $prikey) { 28 | return $this->pri2pub->decrypt($encryptPie, $prikey); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt/RSA/MultiPub2Pri.php: -------------------------------------------------------------------------------- 1 | 2015-03-15 11 | */ 12 | 13 | class PhalApi_Crypt_RSA_MultiPub2Pri extends PhalApi_Crypt_RSA_MultiBase { 14 | 15 | protected $pub2pri; 16 | 17 | public function __construct() { 18 | $this->pub2pri = new PhalApi_Crypt_RSA_Pub2Pri(); 19 | 20 | parent::__construct(); 21 | } 22 | 23 | protected function doEncrypt($toCryptPie, $pubkey) { 24 | return $this->pub2pri->encrypt($toCryptPie, $pubkey); 25 | } 26 | 27 | protected function doDecrypt($encryptPie, $prikey) { 28 | return $this->pub2pri->decrypt($encryptPie, $prikey); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cache/APCU.php: -------------------------------------------------------------------------------- 1 | 2017-04-14 9 | */ 10 | 11 | class PhalApi_Cache_APCU { 12 | 13 | public function __construct() { 14 | if (!extension_loaded('apcu')) { 15 | throw new PhalApi_Exception_InternalServerError( 16 | T('missing {name} extension', array('name' => 'apcu')) 17 | ); 18 | } 19 | } 20 | 21 | public function set($key, $value, $expire = 600) { 22 | return apcu_store($key, $value, $expire); 23 | } 24 | 25 | public function get($key) { 26 | $value = apcu_fetch($key); 27 | return $value !== FALSE ? $value : NULL; 28 | } 29 | 30 | public function delete($key) { 31 | return apcu_delete($key); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Config/Yaconf.php: -------------------------------------------------------------------------------- 1 | 10 | * $config = new PhalApi_Config_Yaconf(); 11 | * 12 | * var_dump($config->get('foo')); //相当于var_dump(Yaconf::get("foo")); 13 | * 14 | * var_dump($config->has('foo')); //相当于var_dump(Yaconf::has("foo")); 15 | * 16 | ``` 17 | * 18 | * @package PhalApi\Config 19 | * @see PhalApi_Config::get() 20 | * @license http://www.phalapi.net/license GPL 协议 21 | * @link http://www.phalapi.net/ 22 | * @link https://github.com/laruence/yaconf 23 | * @author dogstar 2014-10-02 24 | */ 25 | 26 | class PhalApi_Config_Yaconf implements PhalApi_Config { 27 | 28 | public function get($key, $default = NULL) { 29 | return Yaconf::get($key, $default); 30 | } 31 | 32 | public function has($key) { 33 | return Yaconf::has($key); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Config/app.php: -------------------------------------------------------------------------------- 1 | array( 12 | //'sign' => array('name' => 'sign', 'require' => true), 13 | ), 14 | 15 | /** 16 | * 云上传引擎,支持local,oss,upyun 17 | */ 18 | 'UCloudEngine' => 'local', 19 | 20 | /** 21 | * 本地存储相关配置(UCloudEngine为local时的配置) 22 | * 跟主机配置的不一样:可以专门用一个主机存图片 23 | */ 24 | 'UCloud' => array( 25 | //对应的文件路径,调用时:http://xxxx/项目名/文件目录/文件名.jpg 26 | 'host' => 'http://localhost/QuanMin/Public/upload', 27 | 28 | ), 29 | 30 | /** 31 | * 七牛相关配置 32 | */ 33 | 'Qiniu' => array( 34 | //统一的key 35 | 'accessKey' => 'cq4aXQPXylh_9UPqwiU291YH5AJ-MYZWf1ClydOZ', 36 | 'secretKey' => 'gw5_bXMnPf8KtaBIrEzHtEtAO7kUbElNU3XzeoSf', 37 | //自定义配置的空间 38 | 'space_bucket' => 'quanmin', 39 | 'space_host' => 'http://orscb75tu.bkt.clouddn.com', 40 | ), 41 | 42 | ); 43 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Response/JsonP.php: -------------------------------------------------------------------------------- 1 | 2015-02-09 9 | */ 10 | 11 | class PhalApi_Response_JsonP extends PhalApi_Response { 12 | 13 | protected $callback = ''; 14 | 15 | /** 16 | * @param string $callback JS回调函数名 17 | */ 18 | public function __construct($callback) { 19 | $this->callback = $this->clearXss($callback); 20 | 21 | $this->addHeaders('Content-Type', 'text/javascript; charset=utf-8'); 22 | } 23 | 24 | /** 25 | * 对回调函数进行跨站清除处理 26 | * 27 | * - 可使用白名单或者黑名单方式处理,由接口开发再实现 28 | */ 29 | protected function clearXss($callback) { 30 | return $callback; 31 | } 32 | 33 | protected function formatResult($result) { 34 | echo $this->callback . '(' . json_encode($result) . ')'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /qm/Domain/Good.php: -------------------------------------------------------------------------------- 1 | updateGoodCount($count_id, $user_id, $device_code); 14 | return $res; 15 | } 16 | 17 | public function updateBadCount($count_id, $user_id, $device_code) { 18 | $model = new Model_Good(); 19 | $res = $model->updateBadCount($count_id, $user_id, $device_code); 20 | return $res; 21 | } 22 | 23 | public function updateCommentCount($count_id) { 24 | $model = new Model_Good(); 25 | $res = $model->updateCommentCount($count_id); 26 | return $res; 27 | } 28 | 29 | public function updateShareCount($count_id) { 30 | $model = new Model_Good(); 31 | $res = $model->updateShareCount($count_id); 32 | return $res; 33 | } 34 | } -------------------------------------------------------------------------------- /qm/Api/Default.php: -------------------------------------------------------------------------------- 1 | 2014-10-04 6 | */ 7 | 8 | class Api_Default extends PhalApi_Api { 9 | 10 | public function getRules() { 11 | return array( 12 | 'index' => array( 13 | 'username' => array('name' => 'username', 'default' => 'PHPer', ), 14 | ), 15 | ); 16 | } 17 | 18 | /** 19 | * 默认接口服务 20 | * @return string title 标题 21 | * @return string content 内容 22 | * @return string version 版本,格式:X.X.X 23 | * @return int time 当前时间戳 24 | */ 25 | public function index() { 26 | return array( 27 | 'title' => 'Hello World!', 28 | 'content' => T('Hi {name}, welcome to use PhalApi!', array('name' => $this->username)), 29 | 'version' => PHALAPI_VERSION, 30 | 'time' => $_SERVER['REQUEST_TIME'], 31 | ); 32 | } 33 | 34 | /** 35 | * 取消签名验证:重写父类的方法 36 | * 37 | */ 38 | protected function filterCheck () { 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Public/install/_step3.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 安装完成 9 |
10 |
11 |

恭喜您,已安装成功

12 |

接下来,是见证奇迹的时刻,框架的使用,请查看框架使用手册

13 |
14 | 19 |
20 |
21 | 22 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Config.php: -------------------------------------------------------------------------------- 1 | 使用示例:
8 | ``` 9 | * //假设有这样的app.php配置: 10 | * return array( 11 | * 'version' => '1.1.1', 12 | * 13 | * 'email' => array( 14 | * 'address' => 'chanzonghuang@gmail.com', 15 | * ); 16 | * ); 17 | * 18 | * //我们就可以分别这样根据需要获取配置: 19 | * //app.php里面的全部配置 20 | * DI()->config->get('app'); 21 | * 22 | * //app.php里面的单个配置 23 | * DI()->config->get('app.version'); //返回:1.1.1 24 | * 25 | * //app.php里面的多级配置 26 | * DI()->config->get('app.version.address'); //返回:chanzonghuang@gmail.com 27 | ``` 28 | * 29 | * @package PhalApi\Config 30 | * @license http://www.phalapi.net/license GPL 协议 31 | * @link http://www.phalapi.net/ 32 | * @author dogstar 2014-10-02 33 | */ 34 | 35 | interface PhalApi_Config { 36 | 37 | /** 38 | * 获取配置 39 | * 40 | * @param $key string 配置键值 41 | * @param mixed $default 缺省值 42 | * @return mixed 需要获取的配置值,不存在时统一返回$default 43 | */ 44 | public function get($key, $default = NULL); 45 | } 46 | -------------------------------------------------------------------------------- /Library/Qiniu/qiniu/rsf.php: -------------------------------------------------------------------------------- 1 | ($items, $markerOut, $err) 14 | { 15 | global $QINIU_RSF_HOST; 16 | 17 | $query = array('bucket' => $bucket); 18 | if (!empty($prefix)) { 19 | $query['prefix'] = $prefix; 20 | } 21 | if (!empty($marker)) { 22 | $query['marker'] = $marker; 23 | } 24 | if (!empty($limit)) { 25 | $query['limit'] = $limit; 26 | } 27 | 28 | $url = $QINIU_RSF_HOST . '/list?' . http_build_query($query); 29 | list($ret, $err) = Qiniu_Client_Call($self, $url); 30 | if ($err !== null) { 31 | return array(null, '', $err); 32 | } 33 | 34 | $items = $ret['items']; 35 | if (empty($ret['marker'])) { 36 | $markerOut = ''; 37 | $err = Qiniu_RSF_EOF; 38 | } else { 39 | $markerOut = $ret['marker']; 40 | } 41 | return array($items, $markerOut, $err); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Library/Task/Lite.php: -------------------------------------------------------------------------------- 1 | 20150516 6 | */ 7 | 8 | class Task_Lite { 9 | 10 | /** 11 | * Task_MQ $mq MQ队列 12 | */ 13 | protected $mq; 14 | 15 | public function __construct(Task_MQ $mq) { 16 | $this->mq = $mq; 17 | DI()->loader->addDirs('./Library/Task/Task'); 18 | } 19 | 20 | /** 21 | * 添加一个计划任务到MQ队列 22 | * @param string $service 接口服务名称,如:Default.Index 23 | * @param array $params 接口服务参数 24 | */ 25 | public function add($service, $params = array()) { 26 | if (empty($service) || count(explode('.', $service)) < 2) { 27 | return FALSE; 28 | } 29 | if (!is_array($params)) { 30 | return FALSE; 31 | } 32 | 33 | $rs = $this->mq->add($service, $params); 34 | 35 | if (!$rs) { 36 | DI()->logger->debug('task add a new mq', 37 | array('service' => $service, 'params' => $params)); 38 | 39 | return FALSE; 40 | } 41 | 42 | return TRUE; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cache/Multi.php: -------------------------------------------------------------------------------- 1 | 2015-02-22 12 | */ 13 | 14 | class PhalApi_Cache_Multi implements PhalApi_Cache { 15 | 16 | protected $caches = array(); 17 | 18 | public function addCache(PhalApi_Cache $cache) { 19 | $this->caches[] = $cache; 20 | } 21 | 22 | public function set($key, $value, $expire = 600) { 23 | foreach ($this->caches as $cache) { 24 | $cache->set($key, $value, $expire); 25 | } 26 | } 27 | 28 | public function get($key) { 29 | foreach ($this->caches as $cache) { 30 | $value = $cache->get($key); 31 | if ($value !== NULL) { 32 | return $value; 33 | } 34 | } 35 | 36 | return NULL; 37 | } 38 | 39 | public function delete($key) { 40 | foreach ($this->caches as $cache) { 41 | $cache->delete($key); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /qm/Tests/Model/Model_User_Test.php: -------------------------------------------------------------------------------- 1 | modelUser = new Model_User(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGetByUserId 34 | */ 35 | public function testGetByUserId() 36 | { 37 | $userId = '1'; 38 | 39 | $rs = $this->modelUser->getByUserId($userId); 40 | 41 | $this->assertArrayHasKey('id', $rs); 42 | $this->assertArrayHasKey('name', $rs); 43 | $this->assertArrayHasKey('note', $rs); 44 | 45 | $this->assertEquals('dogstar', $rs['name']); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /qm/Tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ./Common 22 | 23 | 24 | ./Api 25 | 26 | 27 | ./Domain 28 | 29 | 30 | ./Model 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /qm/Tests/Domain/Domain_User_Test.php: -------------------------------------------------------------------------------- 1 | domainUser = new Domain_User(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGetBaseInfo 34 | */ 35 | public function testGetBaseInfo() 36 | { 37 | $userId = '1'; 38 | 39 | $rs = $this->domainUser->getBaseInfo($userId); 40 | 41 | $this->assertArrayHasKey('id', $rs); 42 | $this->assertArrayHasKey('name', $rs); 43 | $this->assertArrayHasKey('note', $rs); 44 | 45 | $this->assertEquals('dogstar', $rs['name']); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Library/Task/MQ/Memcached.php: -------------------------------------------------------------------------------- 1 | 20160430 8 | */ 9 | 10 | class Task_MQ_Memcached extends Task_MQ_KeyValue { 11 | 12 | public function __construct(PhalApi_Cache $mcCache = NULL) { 13 | if ($mcCache === NULL) { 14 | $config = DI()->config->get('app.Task.mq.mc'); 15 | if (!isset($config['host'])) { 16 | $config['host'] = '127.0.0.1'; 17 | } 18 | if (!isset($config['port'])) { 19 | $config['port'] = 11211; 20 | } 21 | 22 | //优先使用memcached 23 | $mcCache = extension_loaded('memcached') 24 | ? new PhalApi_Cache_Memcached($config) 25 | : new PhalApi_Cache_Memcache($config); 26 | } 27 | 28 | $mcCache->set('123123', time(), 31536000); 29 | 30 | parent::__construct($mcCache); 31 | } 32 | 33 | /** 34 | * 最大缓存时间,29天,因为MC的过期时间不能超过30天 35 | */ 36 | protected function getExpireTime() { 37 | return 2505600; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Library/Task/Tests/Task_Lite_Test.php: -------------------------------------------------------------------------------- 1 | taskLite = new Task_Lite(new Task_MQ_File()); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAdd 34 | */ 35 | public function testAdd() 36 | { 37 | $service = 'Demo.Update'; 38 | $params = array ( 39 | 'id' => 888 40 | ); 41 | 42 | $rs = $this->taskLite->add($service, $params); 43 | $this->assertTrue($rs); 44 | } 45 | 46 | public function testAddWrong() 47 | { 48 | $service = 'Demo'; 49 | 50 | $rs = $this->taskLite->add($service); 51 | 52 | $this->assertFalse($rs); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Boolean.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | 12 | class PhalApi_Request_Formatter_Boolean extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 13 | 14 | /** 15 | * 对布尔型进行格式化 16 | * 17 | * @param mixed $value 变量值 18 | * @param array $rule array('TRUE' => '成立时替换的内容', 'FALSE' => '失败时替换的内容') 19 | * @return boolean/string 格式化后的变量 20 | * 21 | */ 22 | public function parse($value, $rule) { 23 | $rs = $value; 24 | 25 | if (!is_bool($value)) { 26 | if (is_numeric($value)) { 27 | $rs = $value > 0 ? TRUE : FALSE; 28 | } else if (is_string($value)) { 29 | $rs = in_array(strtolower($value), array('ok', 'true', 'success', 'on', 'yes')) 30 | ? TRUE : FALSE; 31 | } else { 32 | $rs = $value ? TRUE : FALSE; 33 | } 34 | } 35 | 36 | return $rs; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PhalApi/Tests/Request/Formatter/PhalApi_Request_Formatter_Boolean_Test.php: -------------------------------------------------------------------------------- 1 | phalApiRequestFormatterBoolean = new PhalApi_Request_Formatter_Boolean(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testParse 34 | */ 35 | public function testParse() 36 | { 37 | $value = 'on'; 38 | $rule = array(); 39 | 40 | $rs = $this->phalApiRequestFormatterBoolean->parse($value, $rule); 41 | 42 | $this->assertTrue($rs); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /PhalApi/Tests/Request/Formatter/PhalApi_Request_Formatter_Enum.php: -------------------------------------------------------------------------------- 1 | phalApiRequestFormatterEnum = new PhalApi_Request_Formatter_Enum(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testParse 34 | */ 35 | public function testParse() 36 | { 37 | $value = 'ios'; 38 | $rule = array('range' => array('ios', 'android')); 39 | 40 | $rs = $this->phalApiRequestFormatterEnum->parse($value, $rule); 41 | 42 | $this->assertEquals('ios', $rs); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Library/Qiniu/usage/CDN.php: -------------------------------------------------------------------------------- 1 | self::CODE_FAIL_TO_UPLOAD_FILE, 'url' => '', 'msg' => T('fail to upload file')); 17 | 18 | if (!isset($_FILES['file'])) { 19 | $rs['code'] = self::CODE_MISS_UPLOAD_FILE; 20 | $rs['msg'] = T('miss upload file'); 21 | return $rs; 22 | } 23 | 24 | if ($_FILES["file"]["error"] > 0) { 25 | $rs['code'] = self::CODE_FAIL_TO_UPLOAD_FILE; 26 | $rs['msg'] = T('failed to upload file with error: {error}', array('error' => $_FILES['file']['error'])); 27 | DI()->logger->debug('failed to upload file with error: ' . $_FILES['file']['error']); 28 | return $rs; 29 | } 30 | 31 | $url = DI()->qiniu->uploadFile($_FILES['file']['tmp_name']); 32 | if (!empty($url)) { 33 | $rs['code'] = 0; 34 | $rs['url'] = $url; 35 | $rs['msg'] = ''; 36 | } 37 | @unlink($_FILES['file']['tmp_name']); 38 | 39 | return $rs; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /qm/Domain/User.php: -------------------------------------------------------------------------------- 1 | registerWithPhone($phone, $password); 13 | return $user; 14 | } 15 | 16 | /** 17 | * 登录 18 | * 19 | */ 20 | public function login($username, $password, $device_id, $is_line, $mobile_type) 21 | { 22 | $model = new Model_User(); 23 | $user = $model->login($username, $password, $device_id, $is_line, $mobile_type); 24 | return $user; 25 | } 26 | 27 | /** 28 | * 更新用户信息 29 | * 30 | */ 31 | public function updateUserInfo($userId, $userName, $userTruthName, $userAge, $tuserEmail, $userSex, $userQQ, $userPhoto) 32 | { 33 | $model = new Model_User(); 34 | $user = $model->updateUserInfo($userId, $userName, $userTruthName, $userAge, $tuserEmail, $userSex, $userQQ, $userPhoto); 35 | return $user; 36 | } 37 | 38 | /** 39 | * 上传用户头像 40 | * 41 | */ 42 | public function uploadUserPhoto($userId, $userPhoto) 43 | { 44 | $model = new Model_User(); 45 | $user = $model->uploadUserPhoto($userId, $userPhoto); 46 | return $user; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Array.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | 12 | class PhalApi_Request_Formatter_Array extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 13 | 14 | /** 15 | * 对数组格式化/数组转换 16 | * @param string $value 变量值 17 | * @param array $rule array('name' => '', 'type' => 'array', 'default' => '', 'format' => 'json/explode', 'separator' => '', 'min' => '', 'max' => '') 18 | * @return array 19 | */ 20 | public function parse($value, $rule) { 21 | $rs = $value; 22 | 23 | if (!is_array($rs)) { 24 | $ruleFormat = !empty($rule['format']) ? strtolower($rule['format']) : ''; 25 | if ($ruleFormat == 'explode') { 26 | $rs = explode(isset($rule['separator']) ? $rule['separator'] : ',', $rs); 27 | } else if ($ruleFormat == 'json') { 28 | $rs = json_decode($rs, TRUE); 29 | } else { 30 | $rs = array($rs); 31 | } 32 | } 33 | 34 | $this->filterByRange(count($rs), $rule); 35 | 36 | return $rs; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /PhalApi/Tests/Crypt/RSA/PhalApi_Crypt_RSA_Pri2Pub_Test.php: -------------------------------------------------------------------------------- 1 | phalApiCryptRSAPri2Pub = new PhalApi_Crypt_RSA_Pri2Pub(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | public function testHere() 33 | { 34 | $keyG = new PhalApi_Crypt_RSA_KeyGenerator(); 35 | $prikey = $keyG->getPriKey(); 36 | $pubkey = $keyG->getPubkey(); 37 | 38 | $data = 'something important here ...'; 39 | 40 | $encryptData = $this->phalApiCryptRSAPri2Pub->encrypt($data, $prikey); 41 | 42 | $decryptData = $this->phalApiCryptRSAPri2Pub->decrypt($encryptData, $pubkey); 43 | 44 | $this->assertEquals($data, $decryptData); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Library/Task/MQ/Redis.php: -------------------------------------------------------------------------------- 1 | config->get('app.Task.mq.redis'); 10 | 11 | if (!isset($config['host'])) { 12 | $config['host'] = '127.0.0.1'; 13 | } 14 | if (!isset($config['port'])) { 15 | $config['port'] = 6379; 16 | } 17 | if (!isset($config['prefix'])) { 18 | $config['prefix'] = 'phalapi_task'; 19 | } 20 | 21 | $redisCache = new PhalApi_Cache_Redis($config); 22 | } 23 | 24 | $this->redisCache = $redisCache; 25 | } 26 | 27 | public function add($service, $params = array()) { 28 | $num = $this->redisCache->rPush($service, $params); 29 | 30 | return $num > 0 ? TRUE : FALSE; 31 | } 32 | 33 | public function pop($service, $num = 1) { 34 | $rs = array(); 35 | 36 | while($num > 0) { 37 | $params = $this->redisCache->lPop($service); 38 | 39 | if ($params === NULL) { 40 | break; 41 | } 42 | 43 | $rs[] = $params; 44 | 45 | $num--; 46 | } 47 | 48 | return $rs; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /PhalApi/Tests/Request/Formatter/PhalApi_Request_Formatter_Array_Test.php: -------------------------------------------------------------------------------- 1 | phalApiRequestFormatterArray = new PhalApi_Request_Formatter_Array(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testParse 34 | */ 35 | public function testParse() 36 | { 37 | $value = '1|2|3|4|5'; 38 | $rule = array('name' => 'testKey', 'type' => 'array', 'format' => 'explode', 'separator' => '|'); 39 | 40 | $rs = $this->phalApiRequestFormatterArray->parse($value, $rule); 41 | 42 | $this->assertTrue(is_array($rs)); 43 | $this->assertEquals(array(1, 2, 3, 4, 5), $rs); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Library/Qiniu/qiniu/fop.php: -------------------------------------------------------------------------------- 1 | Mode); 18 | 19 | if (!empty($this->Width)) { 20 | $ops[] = 'w/' . $this->Width; 21 | } 22 | if (!empty($this->Height)) { 23 | $ops[] = 'h/' . $this->Height; 24 | } 25 | if (!empty($this->Quality)) { 26 | $ops[] = 'q/' . $this->Quality; 27 | } 28 | if (!empty($this->Format)) { 29 | $ops[] = 'format/' . $this->Format; 30 | } 31 | 32 | return $url . "?imageView/" . implode('/', $ops); 33 | } 34 | } 35 | 36 | // -------------------------------------------------------------------------------- 37 | // class Qiniu_Exif 38 | 39 | class Qiniu_Exif { 40 | 41 | public function MakeRequest($url) 42 | { 43 | return $url . "?exif"; 44 | } 45 | 46 | } 47 | 48 | // -------------------------------------------------------------------------------- 49 | // class Qiniu_ImageInfo 50 | 51 | class Qiniu_ImageInfo { 52 | 53 | public function MakeRequest($url) 54 | { 55 | return $url . "?imageInfo"; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Library/Task/Tests/MQ/Task_MQ_Redis_Test.php: -------------------------------------------------------------------------------- 1 | taskMQRedis = new Task_MQ_Redis(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAdd 34 | */ 35 | public function testAdd() 36 | { 37 | $service = 'TaskRedis.Test'; 38 | $params = array ( 39 | 'id' => 1, 40 | ); 41 | 42 | $rs = $this->taskMQRedis->add($service, $params); 43 | 44 | $this->taskMQRedis->add($service, array('id' => 2)); 45 | } 46 | 47 | /** 48 | * @group testPop 49 | */ 50 | public function testPop() 51 | { 52 | $service = 'TaskRedis.Test'; 53 | $num = 2; 54 | 55 | $rs = $this->taskMQRedis->pop($service, $num); 56 | 57 | $this->assertEquals(array(array('id' => 1), array('id' => 2)), $rs); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Date.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | class PhalApi_Request_Formatter_Date extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 12 | 13 | /** 14 | * 对日期进行格式化 15 | * 16 | * @param timestamp $value 变量值 17 | * @param array $rule array('format' => 'timestamp', 'min' => '最小值', 'max' => '最大值') 18 | * @return timesatmp/string 格式化后的变量 19 | * 20 | */ 21 | public function parse($value, $rule) { 22 | $rs = $value; 23 | 24 | $ruleFormat = !empty($rule['format']) ? strtolower($rule['format']) : ''; 25 | if ($ruleFormat == 'timestamp') { 26 | $rs = strtotime($value); 27 | if ($rs <= 0) { 28 | $rs = 0; 29 | } 30 | 31 | if (isset($rule['min']) && !is_numeric($rule['min'])) { 32 | $rule['min'] = strtotime($rule['min']); 33 | } 34 | if (isset($rule['max']) && !is_numeric($rule['max'])) { 35 | $rule['max'] = strtotime($rule['max']); 36 | } 37 | 38 | $rs = $this->filterByRange($rs, $rule); 39 | } 40 | 41 | return $rs; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SDK/PHP/PhalApiClient/sky.php: -------------------------------------------------------------------------------- 1 | withHost('http://demo.phalapi.net/'); 7 | 8 | $rs = $client->reset() 9 | ->withService('Default.Index') 10 | ->withParams('username', 'dogstar') 11 | ->withTimeout(3000) 12 | ->request(); 13 | 14 | var_dump($rs->getRet()); 15 | echo "\n"; 16 | var_dump($rs->getData()); 17 | echo "\n"; 18 | var_dump($rs->getMsg()); 19 | 20 | /** 21 | 22 | int(200) 23 | 24 | array(4) { 25 | ["title"]=> 26 | string(12) "Hello World!" 27 | ["content"]=> 28 | string(36) "dogstar您好,欢迎使用PhalApi!" 29 | ["version"]=> 30 | string(5) "1.2.1" 31 | ["time"]=> 32 | int(1444925238) 33 | } 34 | 35 | string(0) "" 36 | 37 | */ 38 | 39 | echo "\n--------------------\n"; 40 | 41 | //one more time 42 | $rs = $client->reset() 43 | ->withService("User.GetBaseInfo") 44 | ->withParams("user_id", "1") 45 | ->request(); 46 | 47 | var_dump($rs->getRet()); 48 | echo "\n"; 49 | var_dump($rs->getData()); 50 | echo "\n"; 51 | var_dump($rs->getMsg()); 52 | 53 | 54 | echo "\n--------------------\n"; 55 | 56 | //illegal request 57 | $rs = $client->reset() 58 | ->withService("XXX.XXXXX") 59 | ->withParams("user_id", "1") 60 | ->request(); 61 | 62 | var_dump($rs->getRet()); 63 | echo "\n"; 64 | var_dump($rs->getData()); 65 | echo "\n"; 66 | var_dump($rs->getMsg()); 67 | 68 | -------------------------------------------------------------------------------- /Library/Task/Tests/MQ/Task_MQ_File_Test.php: -------------------------------------------------------------------------------- 1 | taskMQFile = new Task_MQ_File(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAdd 34 | */ 35 | public function testAdd() 36 | { 37 | $service = 'Task_MQ_File_Default.Index'; 38 | $params = array ( 39 | 'username' => 'dogstar', 40 | ); 41 | 42 | $rs = $this->taskMQFile->add($service, $params); 43 | $rs = $this->taskMQFile->add($service, $params); 44 | $rs = $this->taskMQFile->add($service, $params); 45 | } 46 | 47 | /** 48 | * @group testPop 49 | */ 50 | public function testPop() 51 | { 52 | $service = 'Task_MQ_File_Default.Index'; 53 | $num = 2; 54 | 55 | $rs = $this->taskMQFile->pop($service, $num); 56 | $this->assertCount($num, $rs); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /qm/Api/UploadFile.php: -------------------------------------------------------------------------------- 1 | array( 14 | 'video' => array('name' => 'video', 'type' => 'file', 'min' => 0, 'require' => true, 'max' => 50 * 1024 * 1024, 15 | 'range' => array('video/mp4', 'video/x-msvideo'), 'ext' => array('mp4', 'avi'), 'desc' => '视频最大50M' 16 | ) 17 | ), 18 | ); 19 | 20 | } 21 | 22 | /** 23 | * 测试短视频上传接口 24 | * @desc上传短视频 25 | * @return int code 0:数据无更新,1:更新成功,-1:更新失败 26 | * @return string videoUrl 视频地址 27 | * @return string info 提示信息 28 | * http://192.168.1.101/Sky/Public/?service=Upload.UploadShortVideo 29 | */ 30 | public function uploadShortVideo() 31 | { 32 | $res = array('code' => 0, 'info' => '上传成功', 'videoUrl' => ''); 33 | 34 | //设置上传路径:年/月/日 35 | DI()->ucloud->set('save_path', date('Ymd')); 36 | //新增修改文件名设置上传的文件名称 37 | // DI()->ucloud->set('file_name', 'avatar'); 38 | //上传表单名:返回文件信息 39 | $file = DI()->ucloud->upfile($this->video); 40 | 41 | $res['videoUrl'] = $file['file']; 42 | 43 | DI()->logger->debug('文件路径=', $file['file']); 44 | 45 | // ...数据库domain 46 | 47 | return $res; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_CUrl_Test.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | phalApiCUrl = new PhalApi_CUrl(3); 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | } 31 | 32 | 33 | /** 34 | * @group testGet 35 | */ 36 | public function testGet() 37 | { 38 | $url = 'http://demo.phalapi.net/'; 39 | $timeoutMs = 1000; 40 | 41 | $rs = $this->phalApiCUrl->get($url, $timeoutMs); 42 | //var_dump($rs); 43 | 44 | $this->assertTrue(is_string($rs)); 45 | 46 | } 47 | 48 | /** 49 | * @group testPost 50 | */ 51 | public function testPost() 52 | { 53 | $url = 'http://demo.phalapi.net/'; 54 | $data = array('username' => 'phalapi'); 55 | $timeoutMs = 1000; 56 | 57 | $rs = $this->phalApiCUrl->post($url, $data, $timeoutMs); 58 | 59 | $this->assertTrue(is_string($rs)); 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Helper/TestRunner.php: -------------------------------------------------------------------------------- 1 | assertNotEmpty($rs); 16 | * $this->assertArrayHasKey('code', $rs); 17 | * $this->assertArrayHasKey('msg', $rs); 18 | * } 19 | ``` 20 | * 21 | * @package PhalApi\Helper 22 | * @license http://www.phalapi.net/license GPL 协议 23 | * @link http://www.phalapi.net/ 24 | * @author dogstar 2015-05-30 25 | */ 26 | 27 | class PhalApi_Helper_TestRunner { 28 | 29 | /** 30 | * @param string $url 请求的链接 31 | * @param array $param 额外POST的数据 32 | * @return array 接口的返回结果 33 | */ 34 | public static function go($url, $params = array()) { 35 | parse_str($url, $urlParams); 36 | $params = array_merge($urlParams, $params); 37 | 38 | if (!isset($params['service'])) { 39 | throw new PhalApi_Exception(T('miss service in url')); 40 | } 41 | DI()->request = new PhalApi_Request($params); 42 | 43 | $apiObj = PhalApi_ApiFactory::generateService(true); 44 | $action = DI()->request->getServiceAction(); 45 | 46 | $rs = $apiObj->$action(); 47 | 48 | return $rs; 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /Library/Task/MQ/KeyValue.php: -------------------------------------------------------------------------------- 1 | 20160430 8 | */ 9 | 10 | class Task_MQ_KeyValue implements Task_MQ { 11 | 12 | /** 13 | * @var PhalApi_Cache_Memcached/PhalApi_Cache_Memcache/PhalApi_Cache_File $kvCache 缓存实例 14 | */ 15 | protected $kvCache; 16 | 17 | public function __construct(PhalApi_Cache $kvCache) { 18 | $this->kvCache = $kvCache; 19 | } 20 | 21 | public function add($service, $params = array()) { 22 | $list = $this->kvCache->get($service); 23 | if (empty($list)) { 24 | $list = array(); 25 | } 26 | 27 | $list[] = $params; 28 | 29 | $this->kvCache->set($service, $list, $this->getExpireTime()); 30 | 31 | $list = $this->kvCache->get($service); 32 | 33 | return true; 34 | } 35 | 36 | public function pop($service, $num = 1) { 37 | $rs = array(); 38 | if ($num <= 0) { 39 | return $rs; 40 | } 41 | 42 | $list = $this->kvCache->get($service); 43 | if (empty($list)) { 44 | $list = array(); 45 | } 46 | 47 | $rs = array_splice($list, 0, $num); 48 | 49 | $this->kvCache->set($service, $list, $this->getExpireTime()); 50 | 51 | return $rs; 52 | } 53 | 54 | /** 55 | * 最大缓存时间,一年 56 | */ 57 | protected function getExpireTime() { 58 | return 31536000; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /PhalApi/Tests/Cache/PhalApi_Cache_None_Test.php: -------------------------------------------------------------------------------- 1 | phalApiCacheNone = new PhalApi_Cache_None(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testSet 34 | */ 35 | public function testSet() 36 | { 37 | $key = 'aKey'; 38 | $value = 'aValue'; 39 | $expire = '100'; 40 | 41 | $rs = $this->phalApiCacheNone->set($key, $value, $expire); 42 | } 43 | 44 | /** 45 | * @group testGet 46 | */ 47 | public function testGet() 48 | { 49 | $key = 'aKey'; 50 | 51 | $rs = $this->phalApiCacheNone->get($key); 52 | 53 | $this->assertNull($rs); 54 | } 55 | 56 | /** 57 | * @group testDelete 58 | */ 59 | public function testDelete() 60 | { 61 | $key = 'aKey'; 62 | 63 | $rs = $this->phalApiCacheNone->delete($key); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /PhalApi/Tests/Config/PhalApi_Config_Yaconf_Test.php: -------------------------------------------------------------------------------- 1 | phalApiConfigYaconf = new PhalApi_Config_Yaconf(); 32 | } 33 | 34 | protected function tearDown() 35 | { 36 | } 37 | 38 | 39 | /** 40 | * @group testGet 41 | */ 42 | public function testGet() 43 | { 44 | $key = 'test.name'; 45 | $default = NULL; 46 | 47 | $rs = $this->phalApiConfigYaconf->get($key, $default); 48 | 49 | $this->assertEquals('PhalApi', $rs); 50 | } 51 | 52 | /** 53 | * @group testHas 54 | */ 55 | public function testHas() 56 | { 57 | $key = 'test.version'; 58 | 59 | $rs = $this->phalApiConfigYaconf->has($key); 60 | 61 | $this->assertTrue($rs); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /qm/Tests/Api/Api_Default_Test.php: -------------------------------------------------------------------------------- 1 | apiDefault = new Api_Default(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGetRules 34 | */ 35 | public function testGetRules() 36 | { 37 | $rs = $this->apiDefault->getRules(); 38 | 39 | $this->assertNotEmpty($rs); 40 | } 41 | 42 | public function testIndex() 43 | { 44 | //Step 1. 构建请求URL 45 | $url = 'service=Default.Index&username=dogstar'; 46 | 47 | //Step 2. 执行请求 48 | $rs = PhalApi_Helper_TestRunner::go($url); 49 | 50 | //Step 3. 验证 51 | $this->assertNotEmpty($rs); 52 | $this->assertArrayHasKey('title', $rs); 53 | $this->assertArrayHasKey('content', $rs); 54 | $this->assertArrayHasKey('version', $rs); 55 | $this->assertArrayHasKey('time', $rs); 56 | 57 | $this->assertEquals('dogstar您好,欢迎使用PhalApi!', $rs['content']); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Library/Task/Tests/MQ/Task_MQ_Memcached_Test.php: -------------------------------------------------------------------------------- 1 | taskMQMemcached = new Task_MQ_Memcached(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAdd 34 | */ 35 | public function testAdd() 36 | { 37 | $service = 'Task_MQ_Memcached_Default.Index'; 38 | $params = array ( 39 | 'username' => 'dogstar', 40 | ); 41 | 42 | $rs = $this->taskMQMemcached->add($service, $params); 43 | $rs = $this->taskMQMemcached->add($service, $params); 44 | $rs = $this->taskMQMemcached->add($service, $params); 45 | } 46 | 47 | /** 48 | * @group testPop 49 | */ 50 | public function testPop() 51 | { 52 | $service = 'Task_MQ_Memcached_Default.Index'; 53 | $num = 2; 54 | 55 | $rs = $this->taskMQMemcached->pop($service, $num); 56 | $this->assertCount($num, $rs); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Library/Qiniu/qiniu/rs_utils.php: -------------------------------------------------------------------------------- 1 | ($putRet, $err) 8 | { 9 | $putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key"); 10 | $upToken = $putPolicy->Token($self->Mac); 11 | return Qiniu_Put($upToken, $key, $body, $putExtra); 12 | } 13 | 14 | function Qiniu_RS_PutFile($self, $bucket, $key, $localFile, $putExtra) // => ($putRet, $err) 15 | { 16 | $putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key"); 17 | $upToken = $putPolicy->Token($self->Mac); 18 | return Qiniu_PutFile($upToken, $key, $localFile, $putExtra); 19 | } 20 | 21 | function Qiniu_RS_Rput($self, $bucket, $key, $body, $fsize, $putExtra) // => ($putRet, $err) 22 | { 23 | $putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key"); 24 | $upToken = $putPolicy->Token($self->Mac); 25 | if ($putExtra == null) { 26 | $putExtra = new Qiniu_Rio_PutExtra($bucket); 27 | } else { 28 | $putExtra->Bucket = $bucket; 29 | } 30 | return Qiniu_Rio_Put($upToken, $key, $body, $fsize, $putExtra); 31 | } 32 | 33 | function Qiniu_RS_RputFile($self, $bucket, $key, $localFile, $putExtra) // => ($putRet, $err) 34 | { 35 | $putPolicy = new Qiniu_RS_PutPolicy("$bucket:$key"); 36 | $upToken = $putPolicy->Token($self->Mac); 37 | if ($putExtra == null) { 38 | $putExtra = new Qiniu_Rio_PutExtra($bucket); 39 | } else { 40 | $putExtra->Bucket = $bucket; 41 | } 42 | return Qiniu_Rio_PutFile($upToken, $key, $localFile, $putExtra); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /Library/Qiniu/CDN/Api/Qiniu/CDN.php: -------------------------------------------------------------------------------- 1 | self::CODE_FAIL_TO_UPLOAD_FILE, 'url' => '', 'msg' => T('fail to upload file')); 24 | 25 | if (!isset($_FILES['file'])) { 26 | $rs['code'] = self::CODE_MISS_UPLOAD_FILE; 27 | $rs['msg'] = T('miss upload file'); 28 | return $rs; 29 | } 30 | 31 | if ($_FILES["file"]["error"] > 0) { 32 | $rs['code'] = self::CODE_FAIL_TO_UPLOAD_FILE; 33 | $rs['msg'] = T('failed to upload file with error: {error}', array('error' => $_FILES['file']['error'])); 34 | DI()->logger->debug('failed to upload file with error: ' . $_FILES['file']['error']); 35 | return $rs; 36 | } 37 | 38 | $url = DI()->qiniu->uploadFile($_FILES['file']['tmp_name']); 39 | if (!empty($url)) { 40 | $rs['code'] = 0; 41 | $rs['url'] = $url; 42 | $rs['msg'] = ''; 43 | } 44 | @unlink($_FILES['file']['tmp_name']); 45 | 46 | return $rs; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /PhalApi/Tests/Helper/PhalApi_Helper_TestRunner_Test.php: -------------------------------------------------------------------------------- 1 | phalApiHelperTestRunner = new PhalApi_Helper_TestRunner(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGo 34 | */ 35 | public function testGo() 36 | { 37 | $url = 'demo.phalapi.net'; 38 | $params = array ( 39 | 'service' => 'InnerRunner.Go', 40 | ); 41 | 42 | $rs = PhalApi_Helper_TestRunner::go($url, $params); 43 | 44 | $this->assertTrue(is_array($rs)); 45 | } 46 | 47 | /** 48 | * @expectedException PhalApi_Exception 49 | */ 50 | public function testGoWrong() 51 | { 52 | PhalApi_Helper_TestRunner::go('', array()); 53 | } 54 | } 55 | 56 | class APi_InnerRunner extends PhalApi_Api { 57 | 58 | public function go() { 59 | return array('home'); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PhalAPI框架PHP后端API接口开发实践 # 2 | 3 | 努力学习PHP开发ing... 4 | 5 | PhalAPI轻量级开源接口框架:[PhalAPI官网](http://www.phalapi.net)。 6 | 7 | Android端App项目地址:[Android-TianGou](https://github.com/xiao91/Android-TianGou)。 8 | 9 | > 数据库:存放目录:/Data/quanmin.zip。 10 | 11 | > 测试的账号:15000000000(测试用的,请不要尝试去打电话) 12 | 13 | > 密码:123456 14 | 15 | ### 数据库模式 ### 16 | 17 | **粗体是主键,***斜体***是外键** 18 | 19 |

1. 内容:Content(**content_id**, *user_id*, content_detail, content_desc, content_source_url, content_title, content_type, create_time)

20 | 21 |

2. 用户信息:User(**user_id**, username, password, user_age, user_phone, user_email, user_sex, user_qq, user_head, user_type, user_interest, user_address, user_register_time)

22 | 23 |

3. 评论:Comment(**comment_id**, content_id, comment_detail, from_uid, to_uid, username, user_head, good_count, create_time)

24 | 25 |

4. 关注:Follower(**focus_id**, user_id, uid)

26 | 27 |

5. 点赞、点踩、评论、分享次数统计:Good(**count_id**, content_id, guids, gdids, good_count, buids, bdids, bood_count, comment_count, share_count)

28 | 29 |

6. token标识:Token(**token_id**, token, device_code, mobile_type)

30 | 31 |

7. Android版本:Android(**and_id**, and_version_code, and_version_name, and_download_url, and_version_desc)

32 | 33 | **1.接口列表** 34 | 35 |

接口列表

36 | 37 | **2.内容接口** 38 | 39 |

接口列表

40 | 41 | ### 联系我 ### 42 | 43 | 我的QQ:1693538112 44 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/ModelQuery.php: -------------------------------------------------------------------------------- 1 | 2015-02-22 12 | */ 13 | 14 | class PhalApi_ModelQuery { 15 | 16 | /** 17 | * @var boolean $readCache 是否读取缓存 18 | */ 19 | public $readCache = true; 20 | 21 | /** 22 | * @var boolean $writeCache 是否写入缓存 23 | */ 24 | public $writeCache = true; 25 | 26 | /** 27 | * @var string/int ID 28 | */ 29 | public $id; 30 | 31 | /** 32 | * @var int $timestamp 时间戳 33 | */ 34 | public $timestamp; 35 | 36 | public function __construct($queryArr = array()) { 37 | $this->timestamp = $_SERVER['REQUEST_TIME']; 38 | 39 | if (DI()->debug) { 40 | $this->readCache = FALSE; 41 | $this->writeCache = FALSE; 42 | } 43 | 44 | foreach ($queryArr as $key => $value) { 45 | $this->$key = $value; 46 | } 47 | } 48 | 49 | public function __set($name, $value) { 50 | $this->$name = $value; 51 | } 52 | 53 | public function __get($name) { 54 | if (isset($this->$name)) { 55 | return $this->$name; 56 | } 57 | 58 | return NULL; 59 | } 60 | 61 | public function toArray() { 62 | return get_object_vars($this); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Enum.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | class PhalApi_Request_Formatter_Enum extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 12 | 13 | /** 14 | * 检测枚举类型 15 | * @param string $value 变量值 16 | * @param array $rule array('name' => '', 'type' => 'enum', 'default' => '', 'range' => array(...)) 17 | * @return 当不符合时返回$rule 18 | */ 19 | public function parse($value, $rule) { 20 | $this->formatEnumRule($rule); 21 | 22 | $this->formatEnumValue($value, $rule); 23 | 24 | return $value; 25 | } 26 | 27 | /** 28 | * 检测枚举规则的合法性 29 | * @param array $rule array('name' => '', 'type' => 'enum', 'default' => '', 'range' => array(...)) 30 | * @throws PhalApi_Exception_InternalServerError 31 | */ 32 | protected function formatEnumRule($rule) { 33 | if (!isset($rule['range'])) { 34 | throw new PhalApi_Exception_InternalServerError( 35 | T("miss {name}'s enum range", array('name' => $rule['name']))); 36 | } 37 | 38 | if (empty($rule['range']) || !is_array($rule['range'])) { 39 | throw new PhalApi_Exception_InternalServerError( 40 | T("{name}'s enum range can not be empty", array('name' => $rule['name']))); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Filter/SimpleMD5.php: -------------------------------------------------------------------------------- 1 | 2015-10-23 18 | */ 19 | 20 | class PhalApi_Filter_SimpleMD5 implements PhalApi_Filter { 21 | 22 | protected $signName; 23 | 24 | public function __construct($signName = 'sign') { 25 | $this->signName = $signName; 26 | } 27 | 28 | public function check() { 29 | $allParams = DI()->request->getAll(); 30 | if (empty($allParams)) { 31 | return; 32 | } 33 | 34 | $sign = isset($allParams[$this->signName]) ? $allParams[$this->signName] : ''; 35 | unset($allParams[$this->signName]); 36 | 37 | $expectSign = $this->encryptAppKey($allParams); 38 | 39 | if ($expectSign != $sign) { 40 | DI()->logger->debug('Wrong Sign', array('needSign' => $expectSign)); 41 | throw new PhalApi_Exception_BadRequest(T('wrong sign'), 6); 42 | } 43 | } 44 | 45 | protected function encryptAppKey($params) { 46 | ksort($params); 47 | 48 | $paramsStrExceptSign = ''; 49 | foreach ($params as $val) { 50 | $paramsStrExceptSign .= $val; 51 | } 52 | 53 | return md5($paramsStrExceptSign); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /PhalApi/Tests/Filter/PhalApi_Filter_None_Test.php: -------------------------------------------------------------------------------- 1 | phalApiFilterNone = new PhalApi_Filter_None(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testCheck 34 | */ 35 | public function testCheck() 36 | { 37 | $rs = $this->phalApiFilterNone->check(); 38 | } 39 | 40 | /** 41 | * @expectedException Exception 42 | */ 43 | public function testApiWithCheckException() 44 | { 45 | DI()->filter = 'PhalApi_Filter_AlwaysException'; 46 | $api = new Api_Filter_AlwaysException(); 47 | $api->init(); 48 | } 49 | } 50 | 51 | 52 | class Api_Filter_AlwaysException extends PhalApi_Api 53 | { 54 | public function go() 55 | { 56 | return 'go to BeiJing'; 57 | } 58 | } 59 | 60 | class PhalApi_Filter_AlwaysException implements PhalApi_Filter 61 | { 62 | public function check() 63 | { 64 | throw new Exception('just for test'); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_Config_File_Test.php: -------------------------------------------------------------------------------- 1 | coreConfigFile = DI()->config; 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | public function testConstruct() 32 | { 33 | $config = new PhalApi_Config_File(dirname(__FILE__) . '/Config'); 34 | } 35 | 36 | /** 37 | * @group testGet 38 | */ 39 | public function testGetDefault() 40 | { 41 | $key = 'sys.noThisKey'; 42 | $default = 2014; 43 | 44 | $rs = $this->coreConfigFile->get($key, $default); 45 | 46 | $this->assertSame($default, $rs); 47 | } 48 | 49 | public function testGetNormal() 50 | { 51 | $key = 'sys.debug'; 52 | 53 | $rs = $this->coreConfigFile->get($key); 54 | 55 | $this->assertFalse($rs); 56 | } 57 | 58 | public function testGetAll() 59 | { 60 | $key = 'dbs'; 61 | 62 | $rs = $this->coreConfigFile->get($key); 63 | 64 | $this->assertTrue(is_array($rs)); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /PhalApi/Tests/Config/dbs.php: -------------------------------------------------------------------------------- 1 | array( 13 | 'DB_A' => array( 14 | 'host' => '192.168.0.110', //数据库域名 15 | 'name' => 'phalapi_test', //数据库名字 16 | 'user' => 'root', //数据库用户名 17 | 'password' => '123456', //数据库密码 18 | 'port' => '3306', //数据库端口 19 | ), 20 | 'DB_DEMO' => array( 21 | 'host' => '192.168.0.110', //数据库域名 22 | 'name' => 'phalapi_test', //数据库名字 23 | 'user' => 'root', //数据库用户名 24 | 'password' => '123456', //数据库密码 25 | 'port' => '3306', //数据库端口 26 | ), 27 | ), 28 | 29 | /** 30 | * 自定义路由表 31 | */ 32 | 'tables' => array( 33 | '__default__' => array( 34 | 'prefix' => 'tbl_', 35 | 'key' => 'id', 36 | 'map' => array( 37 | array('db' => 'DB_A'), 38 | ), 39 | ), 40 | 'demo' => array( 41 | 'prefix' => 'tbl_', 42 | 'key' => 'id', 43 | 'map' => array( 44 | array('db' => 'DB_A'), 45 | array('start' => 0, 'end' => 2, 'db' => 'DB_A'), 46 | array('start' => 3, 'end' => 5, 'db' => 'DB_DEMO'), 47 | ), 48 | ), 49 | ), 50 | ); 51 | -------------------------------------------------------------------------------- /PhalApi/Tests/Logger/PhalApi_Logger_Explorer_Test.php: -------------------------------------------------------------------------------- 1 | phalApiLoggerExplorer = new PhalApi_Logger_Explorer( 25 | PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR); 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | } 31 | 32 | 33 | /** 34 | * @group testLog 35 | */ 36 | public function testLog() 37 | { 38 | $type = 'test'; 39 | $msg = 'this is a test msg'; 40 | $data = array('from' => 'testLog'); 41 | 42 | $this->phalApiLoggerExplorer->log($type, $msg, $data); 43 | 44 | $this->expectOutputRegex('/TEST|this is a test msg|{"from":"testLog"}/'); 45 | } 46 | 47 | public function testLogButNoShow() 48 | { 49 | $logger = new PhalApi_Logger_Explorer(0); 50 | 51 | $logger->info('no info'); 52 | $logger->debug('no debug'); 53 | $logger->error('no error'); 54 | 55 | $this->expectOutputString(''); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_Cookie_Test.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | phalApiCookie = new PhalApi_Cookie(); 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | } 31 | 32 | 33 | /** 34 | * @group testGet 35 | */ 36 | public function testGet() 37 | { 38 | $key = NULL; 39 | 40 | $rs = $this->phalApiCookie->get($key); 41 | 42 | $this->assertTrue(is_array($rs)); 43 | 44 | $this->assertNull($this->phalApiCookie->get('noThisKey')); 45 | 46 | $_COOKIE['aKey'] = 'phalapi'; 47 | $key = 'aKey'; 48 | $this->assertEquals('phalapi', $this->phalApiCookie->get($key)); 49 | } 50 | 51 | /** 52 | * @group testSet 53 | */ 54 | public function testSet() 55 | { 56 | $key = 'bKey'; 57 | $value = '2015'; 58 | 59 | $rs = @$this->phalApiCookie->set($key, $value); 60 | 61 | //should not get in this time, but next time 62 | $this->assertNull($this->phalApiCookie->get($key)); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Crypt/MultiMcrypt.php: -------------------------------------------------------------------------------- 1 | 2014-12-11 14 | */ 15 | 16 | class PhalApi_Crypt_MultiMcrypt implements PhalApi_Crypt { 17 | 18 | /** 19 | * @var PhalApi_Crypt_Mcrypt $mcrypt 20 | */ 21 | protected $mcrypt = NULL; 22 | 23 | public function __construct($iv) { 24 | $this->mcrypt = new PhalApi_Crypt_Mcrypt($iv); 25 | } 26 | 27 | /** 28 | * @param mixed $data 待加密的数据 29 | */ 30 | public function encrypt($data, $key) { 31 | $encryptData = serialize($data); 32 | 33 | $encryptData = $this->mcrypt->encrypt($encryptData, $key); 34 | 35 | $encryptData = base64_encode($encryptData); 36 | 37 | return $encryptData; 38 | } 39 | 40 | /** 41 | * 忽略不能正常反序列化的操作,并且在不能预期解密的情况下返回原文 42 | */ 43 | public function decrypt($data, $key) { 44 | $decryptData = base64_decode($data); 45 | 46 | if ($decryptData === FALSE || $decryptData === '') { 47 | return $data; 48 | } 49 | 50 | $decryptData = $this->mcrypt->decrypt($decryptData, $key); 51 | 52 | $decryptData = @unserialize($decryptData); 53 | if ($decryptData === FALSE) { 54 | return $data; 55 | } 56 | 57 | return $decryptData; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Library/Task/Task/Model/Task/TaskMq.php: -------------------------------------------------------------------------------- 1 | 20150516 8 | */ 9 | 10 | class Model_Task_TaskMq extends PhalApi_Model_NotORM { 11 | 12 | protected function getTableName($id = NULL) { 13 | $prefix = hexdec(substr(sha1($id), -1)) % 10; 14 | return 'task_mq_' . $prefix; 15 | } 16 | 17 | public function add($service, $params = array()) { 18 | $data = array( 19 | 'service' => $service, 20 | 'params' => json_encode($params), 21 | 'create_time' => time(), 22 | ); 23 | 24 | $id = $this->insert($data, $service); 25 | 26 | return $id > 0 ? TRUE : FALSE; 27 | } 28 | 29 | public function pop($service, $num = 1) { 30 | $rows = $this->getORM($service) 31 | ->select('id, params') 32 | ->where('service', $service) 33 | ->order('id ASC') 34 | ->limit(0, $num) 35 | ->fetchAll(); 36 | 37 | if (empty($rows)) { 38 | return array(); 39 | } 40 | 41 | $ids = array(); 42 | foreach ($rows as $row) { 43 | $ids[] = $row['id']; 44 | } 45 | 46 | $this->getORM($service)->where('id', $ids)->delete(); 47 | 48 | $rs = array(); 49 | foreach ($rows as $row) { 50 | $params = json_decode($row['params'], TRUE); 51 | if (!is_array($params)) { 52 | $params = array(); 53 | } 54 | 55 | $rs[] = $params; 56 | } 57 | 58 | return $rs; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Public/init.php: -------------------------------------------------------------------------------- 1 | loader = $loader; 19 | 20 | //配置 21 | DI()->config = new PhalApi_Config_File(API_ROOT . '/Config'); 22 | 23 | //调试模式,$_GET['__debug__']可自行改名 24 | DI()->debug = !empty($_GET['__debug__']) ? true : DI()->config->get('sys.debug'); 25 | 26 | if (DI()->debug) { 27 | error_reporting(E_ALL); 28 | ini_set('display_errors', 'On'); 29 | } 30 | 31 | //日记纪录 32 | DI()->logger = new PhalApi_Logger_File(API_ROOT . '/Runtime', PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR); 33 | 34 | //数据操作 - 基于NotORM,$_GET['__sql__']可自行改名 35 | DI()->notorm = new PhalApi_DB_NotORM(DI()->config->get('dbs'), !empty($_GET['__sql__'])); 36 | 37 | //翻译语言包设定 38 | SL('zh_cn'); 39 | 40 | /** ---------------- 定制注册 可选服务组件 ---------------- **/ 41 | 42 | DI()->qiniu = new Qiniu_Lite(); 43 | 44 | /** 45 | //签名验证服务 46 | DI()->filter = 'PhalApi_Filter_SimpleMD5'; 47 | */ 48 | 49 | /** 50 | //缓存 - Memcache/Memcached 51 | DI()->cache = function () { 52 | return new PhalApi_Cache_Memcache(DI()->config->get('sys.mc')); 53 | }; 54 | */ 55 | 56 | /** 57 | //支持JsonP的返回 58 | if (!empty($_GET['callback'])) { 59 | DI()->response = new PhalApi_Response_JsonP($_GET['callback']); 60 | } 61 | */ 62 | -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_ModelProxy_Test.php: -------------------------------------------------------------------------------- 1 | phalApiModelProxy = new PhalApi_ModelProxy_Mock(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGetData 34 | */ 35 | public function testGetData() 36 | { 37 | $query = new PhalApi_ModelQuery(); 38 | $query->id = 1; 39 | 40 | $rs = $this->phalApiModelProxy->getData($query); 41 | } 42 | 43 | public function testGetDataWithNoCache() 44 | { 45 | $query = new PhalApi_ModelQuery(); 46 | $query->id = 1; 47 | $query->readCache = false; 48 | $query->writeCache = false; 49 | 50 | $rs = $this->phalApiModelProxy->getData($query); 51 | } 52 | } 53 | 54 | class PhalApi_ModelProxy_Mock extends PhalApi_ModelProxy { 55 | 56 | protected function doGetData($query) { 57 | return 'heavy data'; 58 | } 59 | 60 | protected function getKey($query) { 61 | return 'heavy_data_' . $query->id; 62 | } 63 | 64 | protected function getExpire($query) { 65 | return 10; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Library/Task/Tests/Runner/Task_Runner_Remote_Test.php: -------------------------------------------------------------------------------- 1 | mq = new Task_MQ_Array(); 27 | 28 | $this->taskRunnerRemote = new Task_Runner_Remote($this->mq); 29 | } 30 | 31 | protected function tearDown() 32 | { 33 | } 34 | 35 | public function testHere() 36 | { 37 | $service1 = 'Default.Index'; 38 | $this->mq->add($service1, array('username' => 'phalapi')); 39 | $this->mq->add($service1, array('username' => 'net')); 40 | 41 | $service2 = 'WrongUser.GetBaseInfo'; 42 | $this->mq->add($service2, array('userId' => 1)); 43 | 44 | $rs = $this->taskRunnerRemote->go($service1); 45 | $this->assertEquals(2, $rs['total']); 46 | $this->assertEquals(0, $rs['fail']); 47 | 48 | $rs = $this->taskRunnerRemote->go($service2); 49 | $this->assertEquals(1, $rs['total']); 50 | $this->assertEquals(1, $rs['fail']); 51 | 52 | $rs = $this->taskRunnerRemote->go('TestTaskDemo.Update'); 53 | $this->assertEquals(0, $rs['total']); 54 | $this->assertEquals(0, $rs['fail']); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Library/Task/Tests/Task_Runner_Test.php: -------------------------------------------------------------------------------- 1 | fileMq = new Task_MQ_File(); 27 | $this->taskRunner = new Task_Runner_Mock($this->fileMq); 28 | } 29 | 30 | protected function tearDown() 31 | { 32 | } 33 | 34 | 35 | /** 36 | * @group testGo 37 | */ 38 | public function testGo() 39 | { 40 | $service = 'Demo.TestGo'; 41 | 42 | $this->fileMq->add($service, array()); 43 | $this->fileMq->add($service, array('id' => 123)); 44 | $this->fileMq->add($service, array('id' => 888, 'name' => 'phalapi')); 45 | 46 | $rs = $this->taskRunner->go($service); 47 | //var_dump($rs); 48 | 49 | $this->assertNotEmpty($rs); 50 | $this->assertArrayHasKey('total', $rs); 51 | $this->assertArrayHasKey('fail', $rs); 52 | 53 | $this->assertEquals(3, $rs['total']); 54 | $this->assertEquals(0, $rs['fail']); 55 | } 56 | 57 | } 58 | 59 | class Task_Runner_Mock extends Task_Runner { 60 | 61 | protected function youGo($service, $params) { 62 | echo "Task_Runner_Mock::youGo(", $service , ", ", json_encode($params), ") ... \n"; 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Model.php: -------------------------------------------------------------------------------- 1 | 使用示例:
10 | ``` 11 | * class Model_User extends PhalApi_Model_NotORM { 12 | * 13 | * protected function getTableName($id) { 14 | * return 'user'; 15 | * } 16 | * } 17 | * 18 | * $model = new Model_User(); 19 | * 20 | * // 获取 21 | * $rs = $model->get($userId); 22 | * 23 | * // 插入 24 | * $model->insert(array('name' => 'whatever', 'from' => 'somewhere')); 25 | * 26 | * // 更新 27 | * $model->update(1, array('name' => 'dogstar huang')); 28 | * 29 | * // 删除 30 | * $model->delete(1); 31 | ``` 32 | * 33 | * @package PhalApi\Model 34 | * @license http://www.phalapi.net/license GPL 协议 35 | * @link http://www.phalapi.net/ 36 | * @author dogstar 2015-02-22 37 | */ 38 | 39 | interface PhalApi_Model { 40 | 41 | /** 42 | * 根据主键读取纪录 43 | * 44 | * @param long $id 纪录主键 45 | * @param string/array $fields 需要获取的表字段,可以为字符串(如:name,from)或数组(如:array('name', 'from')) 46 | * @return array 数据库表纪录 47 | */ 48 | public function get($id, $fields = '*'); 49 | 50 | /** 51 | * 插入新纪录 52 | * 这里看起来有点奇怪,但如果我们需要进行分表存储,这里的参考主键是需要的 53 | * 54 | * @param array $data 待插入的数据,可以包括ext_data字段 55 | * @param $id 分表参考主键 56 | * @return long 新插入纪录的主键值 57 | */ 58 | public function insert($data, $id = NULL); 59 | 60 | /** 61 | * 根据主键更新纪录 62 | * 63 | * @param long $id 主键 64 | * @param array $data 待更新的数据,可以包括ext_data字段 65 | * @return TRUE/FALSE 66 | */ 67 | public function update($id, $data); 68 | 69 | /** 70 | * 根据主键删除纪录 71 | */ 72 | public function delete($id); 73 | } 74 | -------------------------------------------------------------------------------- /Library/Task/Tests/MQ/Task_MQ_Array_Test.php: -------------------------------------------------------------------------------- 1 | taskMQArray = new Task_MQ_Array(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAdd 34 | */ 35 | public function testAdd() 36 | { 37 | $service = 'Demo.Test'; 38 | $params = array ( 39 | 'id' => 1, 40 | ); 41 | 42 | $rs = $this->taskMQArray->add($service, $params); 43 | 44 | $this->assertTrue($rs); 45 | } 46 | 47 | /** 48 | * @group testPop 49 | */ 50 | public function testPop() 51 | { 52 | $service = 'Demo.Update'; 53 | $num = '1'; 54 | 55 | $rs = $this->taskMQArray->pop($service, $num); 56 | 57 | $this->assertEmpty($rs); 58 | 59 | $rs = $this->taskMQArray->add($service, array('name' => 'phalapi')); 60 | $rs = $this->taskMQArray->add($service, array('name' => 'net')); 61 | 62 | $rs = $this->taskMQArray->pop($service, 1); 63 | $this->assertEquals(array(array('name' => 'phalapi')), $rs); 64 | $rs = $this->taskMQArray->pop($service, 1); 65 | $this->assertEquals(array(array('name' => 'net')), $rs); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Callable.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | 11 | 12 | class PhalApi_Request_Formatter_Callable extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 13 | 14 | /** 15 | * 对回调类型进行格式化 16 | * 17 | * @param mixed $value 变量值 18 | * @param array $rule array('callback' => '回调函数', 'params' => '第三个参数') 19 | * @return boolean/string 格式化后的变量 20 | * 21 | */ 22 | public function parse($value, $rule) { 23 | $callback = isset($rule['callback']) 24 | ? $rule['callback'] 25 | : (isset($rule['callable']) ? $rule['callable'] : NULL); 26 | 27 | // 提前触发回调类的加载,以便能正常回调 28 | if (is_array($callback) && count($callback) >= 2 && is_string($callback[0])) { 29 | // Type 2:静态类方法,如:array('MyClass', 'myCallbackMethod') 30 | class_exists($callback[0]); 31 | } else if (is_string($callback) && preg_match('/(.*)\:\:/', $callback, $macthes)) { 32 | // Type 4:静态类方法,如:'MyClass::myCallbackMethod' 33 | class_exists($macthes[1]); 34 | } 35 | 36 | if (empty($callback) || !is_callable($callback)) { 37 | throw new PhalApi_Exception_InternalServerError( 38 | T('invalid callback for rule: {name}', array('name' => $rule['name'])) 39 | ); 40 | } 41 | 42 | if (isset($rule['params'])) { 43 | return call_user_func($callback, $value, $rule, $rule['params']); 44 | } else { 45 | return call_user_func($callback, $value, $rule); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Config/File.php: -------------------------------------------------------------------------------- 1 | 从配置文件获取参数配置 6 | * 7 | * 使用示例: 8 | *
9 | * 10 | * $config = new PhalApi_Config_File('./Config'); 11 | * $config->get('sys.db.user'); 12 | * 13 | * 14 | * @package PhalApi\Config 15 | * @see PhalApi_Config::get() 16 | * @license http://www.phalapi.net/license GPL 协议 17 | * @link http://www.phalapi.net/ 18 | * @author dogstar 2014-10-02 19 | */ 20 | 21 | class PhalApi_Config_File implements PhalApi_Config { 22 | 23 | /** 24 | * @var string $path 配置文件的目录位置 25 | */ 26 | private $path = ''; 27 | 28 | /** 29 | * @var array $map 配置文件的映射表,避免重复加载 30 | */ 31 | private $map = array(); 32 | 33 | public function __construct($configPath) { 34 | $this->path = $configPath; 35 | } 36 | 37 | /** 38 | * 获取配置 39 | * 首次获取时会进行初始化 40 | * 41 | * @param $key string 配置键值 42 | * @return mixed 需要获取的配置值 43 | */ 44 | public function get($key, $default = NULL) { 45 | $keyArr = explode('.', $key); 46 | $fileName = $keyArr[0]; 47 | 48 | if (!isset($this->map[$fileName])) { 49 | $this->loadConfig($fileName); 50 | } 51 | 52 | $rs = NULL; 53 | $preRs = $this->map; 54 | foreach ($keyArr as $subKey) { 55 | if (!isset($preRs[$subKey])) { 56 | $rs = NULL; 57 | break; 58 | } 59 | $rs = $preRs[$subKey]; 60 | $preRs = $rs; 61 | } 62 | 63 | return $rs !== NULL ? $rs : $default; 64 | } 65 | 66 | /** 67 | * 加载配置文件 68 | * 加载保存配置信息数组的config.php文件,若文件不存在,则将$map置为空数组 69 | * 70 | * @param string $fileName 配置文件路径 71 | * @return array 配置文件对应的内容 72 | */ 73 | private function loadConfig($fileName) { 74 | $config = include($this->path . DIRECTORY_SEPARATOR . $fileName . '.php'); 75 | 76 | $this->map[$fileName] = $config; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /PhalApi/Tests/Cache/PhalApi_Cache_APCU_Test.php: -------------------------------------------------------------------------------- 1 | aPCU = new PhalApi_Cache_APCU(); 24 | 25 | $this->aPCU->delete('apcu_test_key'); 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | } 31 | 32 | 33 | /** 34 | * @group testSet 35 | */ 36 | public function testSet() 37 | { 38 | $key = 'apcu_test_key'; 39 | $value = '2017'; 40 | $expire = 60; 41 | 42 | $rs = $this->aPCU->set($key, $value, $expire); 43 | } 44 | 45 | /** 46 | * @group testGet 47 | */ 48 | public function testGet() 49 | { 50 | $key = 'apcu_test_key'; 51 | 52 | $rs = $this->aPCU->get($key); 53 | 54 | $this->assertEquals('2017', $rs); 55 | } 56 | 57 | /** 58 | * @group testDelete 59 | */ 60 | public function testDelete() 61 | { 62 | $key = 'apcu_test_key'; 63 | 64 | $rs = $this->aPCU->delete($key); 65 | $this->assertTrue($rs); 66 | 67 | $this->assertSame(NULL, $this->aPCU->get($key)); 68 | } 69 | 70 | public function testSetAndSetAgain() 71 | { 72 | $key = 'apcu_test_key_again'; 73 | 74 | $this->aPCU->set($key, 'A1', 60); 75 | $this->aPCU->set($key, 'A2', 60); 76 | $this->aPCU->set($key, 'A3', 60); 77 | 78 | $this->assertEquals('A3', $this->aPCU->get($key)); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/String.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 9 | */ 10 | class PhalApi_Request_Formatter_String extends PhalApi_Request_Formatter_Base implements PhalApi_Request_Formatter { 11 | 12 | /** 13 | * 对字符串进行格式化 14 | * 15 | * @param mixed $value 变量值 16 | * @@param array $rule array('len' => ‘最长长度’) 17 | * 18 | * @return string 格式化后的变量 19 | */ 20 | public function parse($value, $rule) { 21 | 22 | $rs = strval($this->filterByStrLen(strval($value), $rule)); 23 | 24 | $this->filterByRegex($rs, $rule); 25 | 26 | return $rs; 27 | } 28 | 29 | /** 30 | * 根据字符串长度进行截取 31 | */ 32 | protected function filterByStrLen($value, $rule) { 33 | 34 | $lenRule = $rule; 35 | $lenRule['name'] = $lenRule['name'] . '.len'; 36 | $lenValue = !empty($lenRule['format']) ? mb_strlen($value, $lenRule['format']) : strlen($value); 37 | $this->filterByRange($lenValue, $lenRule); 38 | return $value; 39 | } 40 | 41 | /** 42 | * 进行正则匹配 43 | */ 44 | protected function filterByRegex($value, $rule) { 45 | 46 | if (!isset($rule['regex']) || empty($rule['regex'])) { 47 | return; 48 | } 49 | 50 | //如果你看到此行报错,说明提供的正则表达式不合法 51 | if (preg_match($rule['regex'], $value) <= 0) { 52 | throw new PhalApi_Exception_BadRequest(T('{name} can not match {regex}', array('name' => $rule['name'], 53 | 'regex' => $rule['regex'] 54 | ))); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Public/install/_header.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 快速安装 - PhalApi 13 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 54 | 55 | 56 |
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /Library/Task/Tests/MQ/Task_MQ_DB_Test.php: -------------------------------------------------------------------------------- 1 | taskMQDB = new Task_MQ_DB(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAdd 34 | */ 35 | public function testAdd() 36 | { 37 | $service = 'Demo.Test'; 38 | $params = array ( 39 | 'id' => 1, 40 | ); 41 | 42 | $rs = $this->taskMQDB->add($service, $params); 43 | 44 | $this->assertTrue($rs); 45 | } 46 | 47 | /** 48 | * @group testPop 49 | */ 50 | public function testPop() 51 | { 52 | $this->assertEmpty($this->taskMQDB->pop('NoThisServcie.Index')); 53 | 54 | $service = 'Demo.Update'; 55 | $num = '1'; 56 | $rs = $this->taskMQDB->add($service, array('name' => 'phalapi')); 57 | $rs = $this->taskMQDB->add($service, array('name' => 'net')); 58 | $rs = $this->taskMQDB->add($service, array('name' => 'net')); 59 | $rs = $this->taskMQDB->add($service, array('name' => 'net')); 60 | 61 | $rs = $this->taskMQDB->pop($service, 1); 62 | $this->assertEquals(array(array('name' => 'phalapi')), $rs); 63 | $rs = $this->taskMQDB->pop($service, 2); 64 | $this->assertEquals(array(array('name' => 'net'), array('name' => 'net')), $rs); 65 | 66 | $rs = $this->taskMQDB->pop($service, 10); 67 | $this->assertCount(1, $rs); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /PhalApi/Tests/Cache/PhalApi_Cache_Multi_Test.php: -------------------------------------------------------------------------------- 1 | phalApiCacheMulti = new PhalApi_Cache_Multi(); 25 | 26 | $fileCache = new PhalApi_Cache_File(array('path' => dirname(__FILE__))); 27 | 28 | $this->phalApiCacheMulti->addCache($fileCache); 29 | } 30 | 31 | protected function tearDown() 32 | { 33 | } 34 | 35 | 36 | /** 37 | * @group testAddCache 38 | */ 39 | public function testAddCache() 40 | { 41 | $cache = new PhalApi_Cache_None(); 42 | 43 | $rs = $this->phalApiCacheMulti->addCache($cache); 44 | } 45 | 46 | /** 47 | * @group testSet 48 | */ 49 | public function testSet() 50 | { 51 | $key = 'multiKey'; 52 | $value = 'haha~'; 53 | $expire = '100'; 54 | 55 | $rs = $this->phalApiCacheMulti->set($key, $value, $expire); 56 | } 57 | 58 | /** 59 | * @group testGet 60 | * @depends testSet 61 | */ 62 | public function testGet() 63 | { 64 | $key = 'multiKey'; 65 | 66 | $rs = $this->phalApiCacheMulti->get($key); 67 | 68 | $this->assertSame('haha~', $rs); 69 | } 70 | 71 | /** 72 | * @group testDelete 73 | */ 74 | public function testDelete() 75 | { 76 | $key = 'multiKey'; 77 | 78 | $rs = $this->phalApiCacheMulti->delete($key); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_ModelQuery_Test.php: -------------------------------------------------------------------------------- 1 | phalApiModelQuery = new PhalApi_ModelQuery(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | public function testMixed() 32 | { 33 | $this->phalApiModelQuery->name = 'dogstar'; 34 | 35 | $this->assertEquals('dogstar', $this->phalApiModelQuery->name); 36 | 37 | $this->assertNull($this->phalApiModelQuery->noThisKey); 38 | 39 | $this->assertTrue($this->phalApiModelQuery->readCache); 40 | $this->assertTrue($this->phalApiModelQuery->writeCache); 41 | } 42 | 43 | /** 44 | * @group testToArray 45 | */ 46 | public function testToArray() 47 | { 48 | $rs = $this->phalApiModelQuery->toArray(); 49 | 50 | $this->assertTrue(is_array($rs)); 51 | 52 | $this->assertTrue($rs['readCache']); 53 | $this->assertTrue($rs['writeCache']); 54 | } 55 | 56 | public function testConstructFromToArray() 57 | { 58 | $query = new PhalApi_ModelQuery(); 59 | $query->readCache = false; 60 | $query->name = 'phpunit'; 61 | 62 | $query2 = new PhalApi_ModelQuery($query->toArray()); 63 | 64 | $this->assertEquals('phpunit', $query2->name); 65 | 66 | $this->assertEquals($query->toArray(), $query2->toArray()); 67 | $this->assertEquals($query, $query2); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Library/Task/Runner/Remote.php: -------------------------------------------------------------------------------- 1 | 20150516 8 | */ 9 | 10 | class Task_Runner_Remote extends Task_Runner { 11 | 12 | /** 13 | * @var Task_Runner_Remote_Connector 远程接口连接器实例 14 | */ 15 | protected $contector; 16 | 17 | /** 18 | * @var int $timeoutMS 接口超时(单位:毫秒) 19 | */ 20 | protected $timeoutMS; 21 | 22 | /** 23 | * @var int 默认最大接口超时 24 | */ 25 | const MAX_TIMEOUT_MS = 3000; 26 | 27 | public function __construct(Task_MQ $mq, $step = 10, Task_Runner_Remote_Connector $contector = NULL) { 28 | $config = DI()->config->get('app.Task.runner.remote'); 29 | 30 | if ($contector === NULL) { 31 | if (empty($config['host'])) { 32 | throw new PhalApi_Exception_InternalServerError(T('task miss api host for')); 33 | } 34 | $contector = new Task_Runner_Remote_Connector_Http($config); 35 | } 36 | 37 | $this->contector = $contector; 38 | $this->timeoutMS = isset($config['timeoutMS']) ? intval($config['timeoutMS']) : self::MAX_TIMEOUT_MS; 39 | 40 | parent::__construct($mq, $step); 41 | } 42 | 43 | protected function youGo($service, $params) { 44 | $rs = $this->contector->request($service, $params, $this->timeoutMS); 45 | 46 | if ($this->contector->getRet() == 404) { 47 | throw PhalApi_Exception_InternalServerError('task request api time out', 48 | array('url' => $this->contector->getUrl())); 49 | } 50 | 51 | $isOk = $this->contector->getRet() == 200 ? TRUE : FALSE; 52 | 53 | if (!$isOk) { 54 | DI()->logger->debug('task remote request not ok', 55 | array('url' => $this->contector->getUrl(), 'ret' => $this->contector->getRet(), 'msg' => $this->contector->getMsg())); 56 | } 57 | 58 | return $isOk; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Library/Task/Tests/Runner/Task_Runner_Local_Test.php: -------------------------------------------------------------------------------- 1 | mq = new Task_MQ_Array(); 27 | 28 | $this->taskRunnerLocal = new Task_Runner_Local($this->mq); 29 | } 30 | 31 | protected function tearDown() 32 | { 33 | } 34 | 35 | public function testHere() 36 | { 37 | $service1 = 'TestTaskDemo.Update1'; 38 | $this->mq->add($service1, array('name' => 'phalapi')); 39 | $this->mq->add($service1, array('name' => 'net')); 40 | 41 | $service2 = 'TestTaskDemo.Update2'; 42 | $this->mq->add($service2, array('id' => 1)); 43 | 44 | $rs = $this->taskRunnerLocal->go($service1); 45 | $this->assertEquals(2, $rs['total']); 46 | $this->assertEquals(0, $rs['fail']); 47 | 48 | $rs = $this->taskRunnerLocal->go($service2); 49 | $this->assertEquals(1, $rs['total']); 50 | $this->assertEquals(1, $rs['fail']); 51 | 52 | $rs = $this->taskRunnerLocal->go('TestTaskDemo.Update3'); 53 | $this->assertEquals(0, $rs['total']); 54 | $this->assertEquals(0, $rs['fail']); 55 | } 56 | 57 | } 58 | 59 | class Api_TestTaskDemo extends PhalApi_Api { 60 | 61 | public function update1() { 62 | return array('code' => 0); 63 | } 64 | 65 | public function update2() { 66 | throw new PhalApi_Exception_InternalServerError('just for test'); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /PhalApi/Language/en/common.php: -------------------------------------------------------------------------------- 1 | 'service ({service}) illegal', 6 | 'no such service as {service}' => 'no such service as {service}', 7 | 'mcrypt_module_open with {cipher}' => 'mcrypt_module_open with {cipher}', 8 | 'No table map config for {tableName}' => 'No table map config for {tableName}', 9 | 'Call to undefined method PhalApi_DI::{name}() .' => 'Call to undefined method PhalApi_DI::{name}() .', 10 | "miss {name}'s enum range" => "miss {name}'s enum range", 11 | '{name} should be in {range}, but now {name} = {value}' => '{name} should be in {range}, but now {name} = {value}', 12 | "min should <= max, but now {name} min = {min} and max = {max}" => 'min should <= max, but now {name} min = {min} and max = {max}', 13 | '{name} should >= {min}, but now {name} = {value}' => '{name} should >= {min}, but now {name} = {value}', 14 | 'miss name for rule' => 'miss name for rule', 15 | '{name} require, but miss' => '{name} require, but miss', 16 | 'PhalApi_Api::${name} undefined' => 'PhalApi_Api::${name} undefined', 17 | 'Bad Request: {message}' => 'Bad Request: {message}', 18 | 'Interal Server Error: {message}' => 'Interal Server Error: {message}', 19 | "{name}'s enum range can not be empty" => "{name}'s enum range can not be empty", 20 | 'DI()->filter should be instanceof PhalApi_Filter' => 'DI()->filter should be instanceof PhalApi_Filter', 21 | 'wrong sign' => 'wrong sign', 22 | 'invalid type: {type} for rule: {name}' => 'invalid type: {type} for rule: {name}', 23 | 'invalid callback for rule: {name}' => 'invalid callback for rule: {name}', 24 | 'redis config key [socket] not found' => 'redis config key [socket] not found', 25 | '{name} can not match {regex}' => '{name} can not match {regex}', 26 | 'missing {name} extension' => 'missing {name} extension', 27 | ); 28 | -------------------------------------------------------------------------------- /PhalApi/Tests/Helper/PhalApi_Helper_ApiDesc_Test.php: -------------------------------------------------------------------------------- 1 | loader->addDirs(dirname(__FILE__) . '/../../../Demo'); 12 | 13 | if (!class_exists('PhalApi_Helper_ApiDesc')) { 14 | require dirname(__FILE__) . '/../../PhalApi/Helper/ApiDesc.php'; 15 | } 16 | 17 | class PhpUnderControl_PhalApiHelperApiDesc_Test extends PHPUnit_Framework_TestCase 18 | { 19 | public $phalApiHelperApiDesc; 20 | 21 | protected function setUp() 22 | { 23 | parent::setUp(); 24 | 25 | $this->phalApiHelperApiDesc = new PhalApi_Helper_ApiDesc(); 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | } 31 | 32 | 33 | /** 34 | * @group testRender 35 | */ 36 | public function testRenderDefault() 37 | { 38 | DI()->request = new PhalApi_Request(array()); 39 | $rs = $this->phalApiHelperApiDesc->render(); 40 | 41 | $this->expectOutputRegex("/Default.Index/"); 42 | } 43 | 44 | public function testRenderError() 45 | { 46 | DI()->request = new PhalApi_Request(array('service' => 'NoThisClass.NoThisMethod')); 47 | $rs = $this->phalApiHelperApiDesc->render(); 48 | 49 | $this->expectOutputRegex("/NoThisClass.NoThisMethod/"); 50 | } 51 | 52 | public function testRenderNormal() 53 | { 54 | DI()->request = new PhalApi_Request(array('service' => 'Helper_User_Mock.GetBaseInfo')); 55 | $rs = $this->phalApiHelperApiDesc->render(); 56 | 57 | $this->expectOutputRegex("/Helper_User_Mock.GetBaseInfo/"); 58 | } 59 | } 60 | 61 | class Api_Helper_User_Mock extends PhalApi_Api { 62 | 63 | /** 64 | * @param int user_id ID 65 | * @return int code sth... 66 | */ 67 | public function getBaseInfo() { 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /PhalApi/Tests/Filter/PhalApi_Filter_SimpleMd5_Test.php: -------------------------------------------------------------------------------- 1 | phalApiFilterSimpleMD5 = new PhalApi_Filter_SimpleMD5(); 25 | DI()->filter = 'PhalApi_Filter_SimpleMD5'; 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | DI()->filter = NULL; 31 | } 32 | 33 | 34 | /** 35 | * @group testCheck 36 | */ 37 | public function testCheck() 38 | { 39 | $rs = $this->phalApiFilterSimpleMD5->check(); 40 | } 41 | 42 | /** 43 | * @expectedException PhalApi_Exception_BadRequest 44 | */ 45 | public function testCheckException() 46 | { 47 | $data = array( 48 | 'service' => 'PhalApi_Api_Impl.Add', 49 | 'left' => 1, 50 | 'right' => 1, 51 | ); 52 | DI()->request = new PhalApi_Request($data); 53 | 54 | $api = new PhalApi_Api_Impl(); 55 | $api->init(); 56 | } 57 | 58 | public function testCheckWithRightSign() 59 | { 60 | $data = array( 61 | 'service' => 'PhalApi_Api_Impl.Add', 62 | 'left' => 1, 63 | 'right' => 1, 64 | 'sign' => 'd5c2ea888a6390de5210b9496a1b787a', 65 | ); 66 | DI()->request = new PhalApi_Request($data); 67 | 68 | $api = new PhalApi_Api_Impl(); 69 | $api->init(); 70 | $rs = $api->add(); 71 | 72 | $this->assertEquals(2, $rs); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Public/install/_step1.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 | 7 | 安装向导 8 |
9 |
10 |

环境检查

11 |
为了确保框架正常使用, 您的服务器需要满足以下系统需求的运行环境
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | 30 |
'; 23 | } else { 24 | echo ''; 25 | } 26 | ?>
31 | 35 |
36 |
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /Library/Qiniu/Lite.php: -------------------------------------------------------------------------------- 1 | config = $config; 26 | 27 | if ($this->config === NULL) { 28 | $this->config = DI()->config->get('app.Qiniu'); 29 | } 30 | 31 | DI()->loader->addDirs('./Library/Qiniu/CDN'); 32 | } 33 | 34 | /** 35 | * 文件上传 36 | * @param string $filePath 待上传文件的绝对路径 37 | * @return string 上传成功后的URL,失败时返回空 38 | */ 39 | public function uploadFile($filePath) 40 | { 41 | $fileUrl = ''; 42 | 43 | if (!file_exists($filePath)) { 44 | return $fileUrl; 45 | } 46 | 47 | $config = $this->config; 48 | $fileName = date('YmdHis_', $_SERVER['REQUEST_TIME']) 49 | . md5(PhalApi_Tool::createRandStr(8) . microtime(true)); 50 | 51 | Qiniu_SetKeys($config['accessKey'], $config['secretKey']); 52 | $putPolicy = new Qiniu_RS_PutPolicy($config['space_bucket']); 53 | $upToken = $putPolicy->Token(null); 54 | $putExtra = new Qiniu_PutExtra(); 55 | $putExtra->Crc32 = 1; 56 | list($ret, $err) = Qiniu_PutFile($upToken, $fileName, $filePath, $putExtra); 57 | 58 | if ($err !== null) { 59 | DI()->logger->debug('failed to upload file to qiniu', 60 | array('Err' => $err->Err, 'Reqid' => $err->Reqid, 'Details' => $err->Details, 'Code' => $err->Code)); 61 | } else { 62 | $fileUrl = $config['space_host'] . '/' . $fileName; 63 | DI()->logger->debug('succeed to upload file to qiniu', $ret); 64 | } 65 | 66 | return $fileUrl; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cookie/Multi.php: -------------------------------------------------------------------------------- 1 | 2015-04-11 12 | */ 13 | 14 | class PhalApi_Cookie_Multi extends PhalApi_Cookie { 15 | 16 | /** 17 | * @param $config['crypt'] 加密的服务,如果未设置,默认取DI()->crypt,须实现PhalApi_Crypt接口 18 | * @param $config['key'] $config['crypt']用的密钥,未设置时有一个md5串 19 | */ 20 | public function __construct($config = array()) { 21 | parent::__construct($config); 22 | 23 | $this->config['crypt'] = isset($config['crypt']) ? $config['crypt'] : DI()->crypt; 24 | 25 | if (isset($config['crypt']) && $config['crypt'] instanceof PhalApi_Crypt) { 26 | $this->config['key'] = isset($config['key']) 27 | ? $config['key'] : 'debcf37743b7c835ba367548f07aadc3'; 28 | } else { 29 | $this->config['crypt'] = NULL; 30 | } 31 | } 32 | 33 | /** 34 | * 解密获取COOKIE 35 | * @see PhalApi_Cookie::get() 36 | */ 37 | public function get($name = NULL) { 38 | $rs = parent::get($name); 39 | 40 | if (!isset($this->config['crypt'])) { 41 | return $rs; 42 | } 43 | 44 | if (is_array($rs)) { 45 | foreach ($rs as &$valueRef) { 46 | $this->config['crypt']->decrypt($valueRef, $this->config['key']); 47 | } 48 | } else if ($rs !== NULL) { 49 | $rs = $this->config['crypt']->decrypt($rs, $this->config['key']); 50 | } 51 | 52 | return $rs; 53 | } 54 | 55 | /** 56 | * 加密设置COOKIE&记忆功能 57 | * @see PhalApi_Cookie::set() 58 | */ 59 | public function set($name, $value, $expire = NULL) { 60 | if (isset($this->config['crypt'])) { 61 | $value = $this->config['crypt']->encrypt($value, $this->config['key']); 62 | } 63 | 64 | $_COOKIE[$name] = $value; 65 | if ($expire < $_SERVER['REQUEST_TIME']) { 66 | unset($_COOKIE[$name]); 67 | } 68 | 69 | return parent::set($name, $value, $expire); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_Loader_Test.php: -------------------------------------------------------------------------------- 1 | coreLoader = DI()->loader; 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testAddDirs 34 | */ 35 | public function testAddDirs() 36 | { 37 | $dirs = array('FirstDir', 'SecondDir'); 38 | 39 | $this->coreLoader->addDirs($dirs); 40 | } 41 | 42 | /** 43 | * @group testSetBasePath 44 | */ 45 | public function testSetBasePath() 46 | { 47 | $path = PHALAPI_ROOT; 48 | 49 | $rs = $this->coreLoader->setBasePath($path); 50 | } 51 | 52 | /** 53 | * @group testLoadFile 54 | */ 55 | public function testLoadFile() 56 | { 57 | $filePath = dirname(__FILE__) . '/test_file_for_loader.php'; 58 | 59 | $this->coreLoader->loadFile($filePath); 60 | } 61 | 62 | /** 63 | * @group testLoad 64 | */ 65 | public function testLoad() 66 | { 67 | $className = 'PhalApi_Api'; 68 | 69 | $rs = $this->coreLoader->load($className); 70 | } 71 | 72 | public function testLoadOnce() 73 | { 74 | $obj = new PhalApi_Logger_File('./', 0); 75 | } 76 | 77 | public function testRegisterAgain() 78 | { 79 | $loader = new PhalApi_Loader('./', array()); 80 | $loader = new PhalApi_Loader('./', array()); 81 | 82 | $obj = new PhalApi_DB_NotORM(array()); 83 | } 84 | 85 | public function testConstructAndAdd() 86 | { 87 | $loader = new PhalApi_Loader('./', array('./Config')); 88 | $loader->addDirs('./Data'); 89 | $loader->addDirs(array('./Crypt')); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Library/Task/Runner.php: -------------------------------------------------------------------------------- 1 | 20150516 9 | */ 10 | 11 | abstract class Task_Runner { 12 | 13 | /** 14 | * @var MQ队列实例 15 | */ 16 | protected $mq; 17 | 18 | /** 19 | * @var int $step 批次的数据,步长 20 | */ 21 | protected $step; 22 | 23 | /** 24 | * @param Task_MQ $mq MQ队列实例 25 | * @param int $step 批次的数据,步长 26 | */ 27 | public function __construct(Task_MQ $mq, $step = 10) { 28 | $this->mq = $mq; 29 | 30 | $this->step = max(1, intval($step)); 31 | } 32 | 33 | /** 34 | * 执行任务 35 | * @param string $service MQ中的接口服务名称,如:Default.Index 36 | * @return array('total' => 总数量, 'fail' => 失败数量) 37 | */ 38 | public function go($service) { 39 | $rs = array('total' => 0, 'fail' => 0); 40 | 41 | $todoList = $this->mq->pop($service, $this->step); 42 | $failList = array(); 43 | 44 | while (!empty($todoList)) { 45 | $rs['total'] += count($todoList); 46 | 47 | foreach ($todoList as $params) { 48 | try { 49 | $isFinish = $this->youGo($service, $params); 50 | 51 | if (!$isFinish) { 52 | $rs['fail'] ++; 53 | } 54 | } catch (PhalApi_Exception_InternalServerError $ex) { 55 | $rs['fail'] ++; 56 | 57 | $failList[] = $params; 58 | 59 | DI()->logger->error('task occur exception to go', 60 | array('service' => $service, 'params' => $params, 'error' => $ex->getMessage())); 61 | } 62 | } 63 | 64 | $todoList = $this->mq->pop($service, $this->step); 65 | } 66 | 67 | foreach ($failList as $params) { 68 | $this->mq->add($service, $params); 69 | } 70 | 71 | return $rs; 72 | } 73 | 74 | /** 75 | * 具体的执行,这里使用了一个彩蛋的命名 76 | * @param string $service MQ中的接口服务名称,如:Default.Index 77 | * @param array $params 参数 78 | * @return boolean 成功返回TRUE,失败返回FALSE 79 | */ 80 | abstract protected function youGo($service, $params); 81 | } 82 | -------------------------------------------------------------------------------- /PhalApi/Tests/Request/Formatter/PhalApi_Request_Formatter_Date_Test.php: -------------------------------------------------------------------------------- 1 | phalApiRequestFormatterDate = new PhalApi_Request_Formatter_Date(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testParse 34 | */ 35 | public function testParse() 36 | { 37 | $value = '2014-10-01 12:00:00'; 38 | $rule = array('name' => 'testKey', 'type' => 'date', 'format' => 'timestamp'); 39 | 40 | $rs = $this->phalApiRequestFormatterDate->parse($value, $rule); 41 | 42 | $this->assertTrue(is_numeric($rs)); 43 | $this->assertSame(1412136000, $rs); 44 | } 45 | 46 | public function testParseWithMinAndMax() 47 | { 48 | $value = '2014-10-01 12:00:00'; 49 | $rule = array('name' => 'testKey', 'type' => 'date', 'format' => 'timestamp', 'min' => strtotime('2014-10-01 00:00:00'), 'max' => strtotime('2014-10-01 23:59:59')); 50 | 51 | $rs = $this->phalApiRequestFormatterDate->parse($value, $rule); 52 | 53 | $this->assertTrue(is_numeric($rs)); 54 | $this->assertSame(1412136000, $rs); 55 | } 56 | 57 | public function testParseWithMinAndMaxForString() 58 | { 59 | $value = '2014-10-01 12:00:00'; 60 | $rule = array('name' => 'testKey', 'type' => 'date', 'format' => 'timestamp', 'min' => '2014-10-01 00:00:00', 'max' => '2014-10-01 23:59:59'); 61 | 62 | $rs = $this->phalApiRequestFormatterDate->parse($value, $rule); 63 | 64 | $this->assertTrue(is_numeric($rs)); 65 | $this->assertSame(1412136000, $rs); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /qm/Tests/Api/Api_User_Test.php: -------------------------------------------------------------------------------- 1 | apiUser = new Api_User(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGetRules 34 | */ 35 | public function testGetRules() 36 | { 37 | $rs = $this->apiUser->getRules(); 38 | } 39 | 40 | /** 41 | * @group testGetBaseInfo 42 | */ 43 | public function testGetBaseInfo() 44 | { 45 | //Step 1. 构建请求URL 46 | $url = 'service=User.GetBaseInfo&user_id=1'; 47 | 48 | //Step 2. 执行请求 49 | $rs = PhalApi_Helper_TestRunner::go($url); 50 | 51 | //Step 3. 验证 52 | $this->assertNotEmpty($rs); 53 | $this->assertArrayHasKey('code', $rs); 54 | $this->assertArrayHasKey('msg', $rs); 55 | $this->assertArrayHasKey('info', $rs); 56 | 57 | $this->assertEquals(0, $rs['code']); 58 | 59 | $this->assertEquals('dogstar', $rs['info']['name']); 60 | $this->assertEquals('oschina', $rs['info']['note']); 61 | } 62 | 63 | public function testGetMultiBaseInfo() 64 | { 65 | //Step 1. 构建请求URL 66 | $url = 'service=User.GetMultiBaseInfo&user_ids=1,2,3'; 67 | 68 | //Step 2. 执行请求 69 | $rs = PhalApi_Helper_TestRunner::go($url); 70 | 71 | //Step 3. 验证 72 | $this->assertNotEmpty($rs); 73 | $this->assertArrayHasKey('code', $rs); 74 | $this->assertArrayHasKey('msg', $rs); 75 | $this->assertArrayHasKey('list', $rs); 76 | 77 | foreach ($rs['list'] as $item) { 78 | $this->assertArrayHasKey('id', $item); 79 | $this->assertArrayHasKey('name', $item); 80 | $this->assertArrayHasKey('note', $item); 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /Library/Task/Runner/Remote/Connector.php: -------------------------------------------------------------------------------- 1 | 20150516 6 | */ 7 | 8 | abstract class Task_Runner_Remote_Connector { 9 | 10 | protected $host; 11 | 12 | protected $params = array(); 13 | 14 | protected $moreParams = array(); 15 | 16 | protected $url; 17 | protected $ret; 18 | protected $msg; 19 | protected $data = array(); 20 | 21 | public function __construct($config) { 22 | $this->host = $config['host']; 23 | $this->moreParams = isset($config['params']) ? $config['params'] : array(); 24 | } 25 | 26 | /** 27 | * 接口请求,超时时ret为404 28 | * @param string $service MQ中的接口服务名称,如:Default.Index 29 | * @param array $params 参数 30 | * @param int $timeoutMS 接口超时(单位:毫秒) 31 | * @return array 32 | */ 33 | public function request($service, $params = array(), $timeoutMs = 3000) { 34 | $this->url = $this->host . '?service=' . $service; 35 | $params = array_merge($this->moreParams, $params); 36 | 37 | $apiRs = $this->doRequest($this->url, $params, $timeoutMs); 38 | 39 | if ($apiRs === FALSE) { 40 | $this->ret = 404; 41 | $this->msg = T('time out'); 42 | 43 | DI()->logger->debug('task request api time out', array('url' => $this->url)); 44 | 45 | return $this->getData(); 46 | } 47 | 48 | $rs = json_decode($apiRs, true); 49 | 50 | if (empty($rs) || !isset($rs['ret'])) { 51 | $this->ret = 500; 52 | $this->msg = T('nothing return or illegal json: {rs}', array('rs' => $apiRs)); 53 | return $this->getData(); 54 | } 55 | 56 | $this->ret = $rs['ret']; 57 | $this->data = $rs['data']; 58 | $this->msg = $rs['msg']; 59 | 60 | return $this->getData(); 61 | } 62 | 63 | public function getRet() { 64 | return $this->ret; 65 | } 66 | 67 | public function getData() { 68 | return $this->data; 69 | } 70 | 71 | public function getMsg() { 72 | return $this->msg; 73 | } 74 | 75 | public function getUrl() { 76 | return $this->url; 77 | } 78 | 79 | abstract protected function doRequest($url, $data, $timeoutMs); 80 | } 81 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Cache/Memcache.php: -------------------------------------------------------------------------------- 1 | 15/5/6 下午8:53 13 | */ 14 | 15 | class PhalApi_Cache_Memcache implements PhalApi_Cache { 16 | 17 | protected $memcache = null; 18 | 19 | protected $prefix; 20 | 21 | /** 22 | * @param string $config['host'] Memcache域名,多个用英文逗号分割 23 | * @param int/string $config['port'] Memcache端口,多个用英文逗号分割 24 | * @param int/string $config['weight'] Memcache权重,多个用英文逗号分割 25 | * @param string $config['prefix'] Memcache key prefix 26 | */ 27 | public function __construct($config) { 28 | $this->memcache = $this->createMemcache(); 29 | 30 | $hostArr = explode(',', $config['host']); 31 | $portArr = explode(',', $config['port']); 32 | $weightArr = isset($config['weight']) ? explode(',', $config['weight']) : array(); 33 | 34 | foreach ($hostArr as $idx => $host) { 35 | $this->memcache->addServer( 36 | trim($host), 37 | isset($portArr[$idx]) ? intval($portArr[$idx]) : 11211, 38 | isset($weightArr[$idx]) ? intval($weightArr[$idx]) : 0 39 | ); 40 | } 41 | 42 | $this->prefix = isset($config['prefix']) ? $config['prefix'] : 'phalapi_'; 43 | } 44 | 45 | public function set($key, $value, $expire = 600) { 46 | $this->memcache->set($this->formatKey($key), @serialize($value), 0, $expire); 47 | } 48 | 49 | public function get($key) { 50 | $value = $this->memcache->get($this->formatKey($key)); 51 | return $value !== FALSE ? @unserialize($value) : NULL; 52 | } 53 | 54 | public function delete($key) { 55 | return $this->memcache->delete($this->formatKey($key)); 56 | } 57 | 58 | /** 59 | * 获取MC实例,以便提供桩入口 60 | * @return Memcache 61 | */ 62 | protected function createMemcache() { 63 | return new Memcache(); 64 | } 65 | 66 | protected function formatKey($key) { 67 | return $this->prefix . $key; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /PhalApi/PhalApi.php: -------------------------------------------------------------------------------- 1 | 使用示例:
20 | * ``` 21 | * $api = new PhalApi(); 22 | * $rs = $api->response(); 23 | * $rs->output(); 24 | * ``` 25 | * 26 | * @package PhalApi\Response 27 | * @license http://www.phalapi.net/license GPL 协议 28 | * @link http://www.phalapi.net/ 29 | * @author dogstar 2014-12-17 30 | */ 31 | class PhalApi 32 | { 33 | 34 | /** 35 | * 响应操作 36 | * 37 | * 通过工厂方法创建合适的控制器,然后调用指定的方法,最后返回格式化的数据。 38 | * 39 | * @return mixed 根据配置的或者手动设置的返回格式,将结果返回 40 | * 其结果包含以下元素: 41 | * ``` 42 | * array( 43 | * 'ret' => 200, //服务器响应状态 44 | * 'data' => array(), //正常并成功响应后,返回给客户端的数据 45 | * 'msg' => '', //错误提示信息 46 | * ); 47 | * ``` 48 | */ 49 | public function response() 50 | { 51 | $rs = DI()->response; 52 | 53 | try { 54 | // 接口调度与响应 55 | $api = PhalApi_ApiFactory::generateService(); 56 | $action = DI()->request->getServiceAction(); 57 | $data = call_user_func(array($api, $action)); 58 | 59 | $rs->setData($data); 60 | } catch (PhalApi_Exception $ex) { 61 | // 框架或项目可控的异常 62 | $rs->setRet($ex->getCode()); 63 | $rs->setMsg($ex->getMessage()); 64 | } catch (Exception $ex) { 65 | // 不可控的异常 66 | DI()->logger->error(DI()->request->getService(), strval($ex)); 67 | 68 | if (DI()->debug) { 69 | $rs->setRet($ex->getCode()); 70 | $rs->setMsg($ex->getMessage()); 71 | $rs->setDebug('exception', $ex->getTrace()); 72 | } else { 73 | throw $ex; 74 | } 75 | } 76 | 77 | $rs->setDebug('stack', DI()->tracer->getStack()); 78 | $rs->setDebug('sqls', DI()->tracer->getSqls()); 79 | 80 | return $rs; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /PhalApi/Tests/Helper/PhalApi_Helper_Tracer_Test.php: -------------------------------------------------------------------------------- 1 | phalApiHelperTracer = new PhalApi_Helper_Tracer(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | DI()->debug = true; 30 | } 31 | 32 | 33 | /** 34 | * @group testMark 35 | */ 36 | public function testMark() 37 | { 38 | $tag = ''; 39 | 40 | $this->phalApiHelperTracer->mark($tag); 41 | $this->phalApiHelperTracer->mark('aHa~'); 42 | } 43 | 44 | /** 45 | * @group testGetReport 46 | */ 47 | public function testGetReport() 48 | { 49 | $rs = $this->phalApiHelperTracer->getStack(); 50 | 51 | $this->assertTrue(is_array($rs)); 52 | } 53 | 54 | public function testMixed() 55 | { 56 | $this->phalApiHelperTracer->mark('aHa~'); 57 | $this->phalApiHelperTracer->mark('BIU~'); 58 | $this->phalApiHelperTracer->mark('BlaBla~'); 59 | 60 | doSthForTrace($this->phalApiHelperTracer); 61 | 62 | $report = $this->phalApiHelperTracer->getStack(); 63 | //var_dump($report); 64 | $this->assertCount(4, $report); 65 | } 66 | 67 | public function testNoDebug() 68 | { 69 | DI()->debug = false; 70 | 71 | $tracer = new PhalApi_Helper_Tracer(); 72 | $tracer->mark('aHa~'); 73 | 74 | $report = $tracer->getStack(); 75 | $this->assertCount(0, $report); 76 | } 77 | 78 | public function testSql() 79 | { 80 | $this->phalApiHelperTracer->sql('SELECT'); 81 | $this->phalApiHelperTracer->sql('DELETE'); 82 | 83 | $this->assertCount(2, $this->phalApiHelperTracer->getSqls()); 84 | } 85 | } 86 | 87 | function doSthForTrace($tracer) { 88 | $tracer->mark('IN_FUNCTION'); 89 | } 90 | -------------------------------------------------------------------------------- /PhalApi/Tests/Cookie/PhalApi_Cookie_Multi_Test.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | new Cookie_Crypt_Mock(), 'key' => 'aha~'); 26 | $this->phalApiCookieMulti = new PhalApi_Cookie_Multi($config); 27 | } 28 | 29 | protected function tearDown() 30 | { 31 | } 32 | 33 | 34 | /** 35 | * @group testGet 36 | */ 37 | public function testGet() 38 | { 39 | $name = NULL; 40 | 41 | $rs = $this->phalApiCookieMulti->get($name); 42 | 43 | $this->assertTrue(is_array($rs)); 44 | 45 | } 46 | 47 | /** 48 | * @group testSet 49 | */ 50 | public function testSet() 51 | { 52 | $name = 'aEKey'; 53 | $value = '2015'; 54 | $expire = $_SERVER['REQUEST_TIME'] + 10; 55 | 56 | $rs = @$this->phalApiCookieMulti->set($name, $value, $expire); 57 | 58 | //remember 59 | $this->assertEquals($value, $this->phalApiCookieMulti->get($name)); 60 | } 61 | 62 | /** 63 | * @group testDelete 64 | */ 65 | public function testDelete() 66 | { 67 | $name = 'aEKey'; 68 | $value = '2015'; 69 | $expire = $_SERVER['REQUEST_TIME'] + 10; 70 | 71 | $rs = @$this->phalApiCookieMulti->set($name, $value, $expire); 72 | 73 | $this->assertNotEmpty($this->phalApiCookieMulti->get($name)); 74 | 75 | $rs = @$this->phalApiCookieMulti->delete($name); 76 | 77 | $this->assertNull($this->phalApiCookieMulti->get($name)); 78 | } 79 | 80 | } 81 | 82 | class Cookie_Crypt_Mock implements PhalApi_Crypt { 83 | 84 | public function encrypt($data, $key) { 85 | return base64_encode($data); 86 | } 87 | 88 | public function decrypt($data, $key) { 89 | return base64_decode($data); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /qm/Model/Focus.php: -------------------------------------------------------------------------------- 1 | 0, 'info' => '', 'focus_id' => ''); 20 | $data = array( 21 | 'user_id' => $user_id, 22 | 'uid' => $uid, 23 | ); 24 | 25 | $focusORM = DI()->notorm->focus; 26 | $focus = $focusORM->insert($data); 27 | 28 | $row = $focusORM->insert_id(); 29 | if ($row == 0) { 30 | $res['code'] = 0; 31 | $res['info'] = '没有更新'; 32 | } elseif ($row > 0) { 33 | $res['code'] = 1; 34 | $res['info'] = '添加关注成功'; 35 | } elseif ($row === false) { 36 | $res['code'] = -1; 37 | $res['info'] = '添加关注失败'; 38 | } 39 | $res['focus_id'] = $focus['focus_id']; 40 | return $res; 41 | } 42 | 43 | /** 44 | * 取消关注 45 | * 46 | */ 47 | public function cancelFocus($focus_id) 48 | { 49 | $res = array('code'=> 0, 'info'=> ''); 50 | 51 | $focusORM = DI()->notorm->focus; 52 | $focus = $focusORM->where('focus_id', $focus_id)->delete(); 53 | 54 | if ($focus > 0) { 55 | $res['code'] = 1; 56 | $res['info'] = '取消关注成功'; 57 | } else { 58 | $res['code'] = -1; 59 | $res['info'] = '取消关注失败'; 60 | } 61 | 62 | return $res; 63 | } 64 | 65 | /** 66 | * 查询有没有关注 67 | * 68 | */ 69 | public function readFocus($user_id, $uid) 70 | { 71 | $res = array('code'=> 0, 'info'=> '', 'focus_id' => ''); 72 | 73 | $focusORM = DI()->notorm->focus; 74 | $sql = 'SELECT focus_id FROM qm_focus WHERE user_id = :user_id AND uid = :uid'; 75 | // 返回的是数组,可能有重复的关注数据 76 | $focus = $focusORM->queryAll($sql, array(':user_id' => $user_id, ':uid' => $uid)); 77 | 78 | if (empty($focus)) { 79 | $res['code'] = -1; 80 | $res['info'] = '未关注'; 81 | } else { 82 | $res['focus_id'] = $focus[0]['focus_id']; 83 | $res['code'] = 1; 84 | $res['info'] = '有关注'; 85 | } 86 | 87 | return $res; 88 | } 89 | } -------------------------------------------------------------------------------- /qm/Api/Focus.php: -------------------------------------------------------------------------------- 1 | array( 14 | 'user_id' => array('name' => 'user_id', 'type' => 'int', 'require' => false, 'desc' => '用户id,第一人'), 15 | 'uid' => array('name' => 'uid', 'type' => 'int', 'require' => true, 'desc' => '用户id,第二人') 16 | ), 17 | 18 | 'cancelFocus' => array( 19 | 'focus_id' => array('name' => 'focus_id', 'type' => 'int', 'require' => false, 'desc' => '关注的id') 20 | ), 21 | 22 | 'readFocus' => array( 23 | 'user_id' => array('name' => 'user_id', 'type' => 'int', 'require' => false, 'desc' => '用户id,第一人'), 24 | 'uid' => array('name' => 'uid', 'type' => 'int', 'require' => true, 'desc' => '用户id,第二人') 25 | ) 26 | ); 27 | } 28 | 29 | /** 30 | * 添加关注 31 | * @desc 添加关注,登录后才能添加 32 | * @return int code 提示码,0:没有更新,1:添加关注成功,-1:添加关注失败 33 | * @return string focus_id 关注的id 34 | * @return string info 提示信息 35 | * 36 | * http://localhost/QuanMin/Public/?service=Focus.AddFocus&user_id=1&uid=8 37 | * 38 | */ 39 | public function addFocus() 40 | { 41 | $focus = new Domain_Focus(); 42 | $res = $focus->addFocus($this->user_id, $this->uid); 43 | return $res; 44 | } 45 | 46 | /** 47 | * 取消关注 48 | * @desc 取消关注,需要登录 49 | * @return int code 提示码,1:取消关注成功,-1:取消关注失败 50 | * @return string info 提示信息 51 | * 52 | * http://localhost/QuanMin/Public/?service=Focus.CancelFocus&focus_id=2 53 | * 54 | */ 55 | public function cancelFocus() 56 | { 57 | $focus = new Domain_Focus(); 58 | $res = $focus->cancelFocus($this->focus_id); 59 | return $res; 60 | } 61 | 62 | /** 63 | * 判断有没有关注 64 | * @desc 判断有没有关注,需要登录 65 | * @return int code 提示码,1:有关注,-1:未关注 66 | * @return string info 提示信息 67 | * 68 | * http://localhost/QuanMin/Public/?service=Focus.ReadFocus&user_id=1&uid=8 69 | * 70 | */ 71 | public function readFocus() 72 | { 73 | $focus = new Domain_Focus(); 74 | $res = $focus->readFocus($this->user_id, $this->uid); 75 | return $res; 76 | } 77 | } -------------------------------------------------------------------------------- /Public/install/_start.php: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 | 6 | 7 | 安装向导 8 |
9 |
10 |

欢迎使用,PhalAPI 框架安装向导

11 |
从现在开始,用另一种想法,重新构建你的应用
12 |
13 |

协议许可的权利

14 |

PhalApi官方网站为 http://www.phalapi.net,依法独立拥有 PhalApi 及官网发布的PhalApi衍生产品著作权。PhalApi及其衍生产品著作权受到法律和国际公约保护。使用者需仔细阅读本协议,在理解、同意、并遵守本协议的全部条款后,方可开始使用 PhalApi及其衍生 软件。

15 |

本授权协议适用于 http://www.phalapi.net 发布的所有应用程序,PhalApi官方网站拥有对本授权协议的最终解释权。

16 |
17 | 18 |

协议规定的约束和限制

19 |

PhalApi软件及其PhalApi官网发布的PhalApi衍生产品在没有相关说明的情况下默认是免费的,可用于商业用途或者非商业用途。但是无论用途如何,是否经过修改,修改程度如何,未经过许可, 页面上的产品名称以及指向官网的连接还有源代码中关于PhalApi的版权信息及作者信息必须保留,不许修改或删除,除非您获得PhalApi官网的许可。

20 |

如果您未能遵守本协议的条款,您的授权将被终止,所被许可的权利将被收回,并承担相应法律责任。

21 |
22 | 23 |

有限担保和免责声明

24 |

本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。 用户出于自愿而使用本软件,您必须了解使用本软件的风险,在尚未购买产品技术服务之前,我们不承诺提供任何形式的技术支持、使用担保,也不承担任何因使用本软件而产生问题的相关责任。 PhalApi官网不对使用本软件及官网发布的衍生产品构建的软件中的文章或信息承担责任。

25 |

有关 PhalApi 最终用户授权协议、商业授权与技术服务的详细内容,均由 PhalApi 官方网站独家提供。PhalApi官网拥有在不事先通知的情况下,修改授权协议和服务价目表的权力,修改后的协议或价目表对自改变之日起的新授权用户生效。 电子文本形式的授权协议如同双方书面签署的协议一样,具有完全的和等同的法律效力。您一旦开始安装 PhalApi以及官网发布的衍生产品,即被视为完全理解并接受本协议的各项条款,在享有上述条款授予的权力的同时,受到相关的约束和限制。 协议许可范围以外的行为,将直接违反本授权协议并构成侵权,我们有权随时终止授权,责令停止损害,并保留追究相关责任的权力。

26 |
27 |
28 | 同意安装 29 | 30 |
31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/ApiFactory.php: -------------------------------------------------------------------------------- 1 | 2014-10-02 15 | */ 16 | 17 | class PhalApi_ApiFactory { 18 | 19 | /** 20 | * 创建服务器 21 | * 根据客户端提供的接口服务名称和需要调用的方法进行创建工作,如果创建失败,则抛出相应的自定义异常 22 | * 23 | * 创建过程主要如下: 24 | * - 1、 是否缺少控制器名称和需要调用的方法 25 | * - 2、 控制器文件是否存在,并且控制器是否存在 26 | * - 3、 方法是否可调用 27 | * - 4、 控制器是否初始化成功 28 | * 29 | * @param boolen $isInitialize 是否在创建后进行初始化 30 | * @param string $_REQUEST['service'] 接口服务名称,格式:XXX.XXX 31 | * @return PhalApi_Api 自定义的控制器 32 | * 33 | * @uses PhalApi_Api::init() 34 | * @throws PhalApi_Exception_BadRequest 非法请求下返回400 35 | */ 36 | static function generateService($isInitialize = TRUE) { 37 | $service = DI()->request->getService(); 38 | $api = DI()->request->getServiceApi(); 39 | $action = DI()->request->getServiceAction(); 40 | 41 | if (empty($api) || empty($action)) { 42 | throw new PhalApi_Exception_BadRequest( 43 | T('service ({service}) illegal', array('service' => $service)) 44 | ); 45 | } 46 | 47 | $apiClass = 'Api_' . ucfirst($api); 48 | if (!class_exists($apiClass)) { 49 | throw new PhalApi_Exception_BadRequest( 50 | T('no such service as {service}', array('service' => $service)), 4 51 | ); 52 | } 53 | 54 | $api = new $apiClass(); 55 | 56 | if (!is_subclass_of($api, 'PhalApi_Api')) { 57 | throw new PhalApi_Exception_InternalServerError( 58 | T('{class} should be subclass of PhalApi_Api', array('class' => $apiClass)) 59 | ); 60 | } 61 | 62 | if (!method_exists($api, $action) || !is_callable(array($api, $action))) { 63 | throw new PhalApi_Exception_BadRequest( 64 | T('no such service as {service}', array('service' => $service)), 4 65 | ); 66 | } 67 | 68 | if ($isInitialize) { 69 | $api->init(); 70 | } 71 | 72 | return $api; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /PhalApi/Tests/Cache/PhalApi_Cache_Memcached_Test.php: -------------------------------------------------------------------------------- 1 | '127.0.0.1', 'port' => '11211'); 25 | $this->phalApiCacheMemcached = new PhalApi_Cache_Memcached($config); 26 | } 27 | 28 | protected function tearDown() 29 | { 30 | } 31 | 32 | 33 | /** 34 | * @group testSet 35 | */ 36 | public function testSet() 37 | { 38 | $key = 'memcached-key'; 39 | $value = 'ECO'; 40 | $expire = 60; 41 | 42 | $rs = $this->phalApiCacheMemcached->set($key, $value, $expire); 43 | 44 | $this->assertEquals('ECO', $this->phalApiCacheMemcached->get($key)); 45 | } 46 | 47 | public function testMultiMemcacheInstance() 48 | { 49 | $config = array( 50 | 'host' => '127.0.0.1, 127.0.0.1', 51 | 'port' => '11211, 11212', 52 | 'weight' => '20, 80', 53 | ); 54 | 55 | $memcache = new PhalApi_Cache_Memcached($config); 56 | 57 | $memcache->set('multi-key-1', 'M1', 60); 58 | $memcache->set('multi-key-2', 'M2', 60); 59 | $memcache->set('multi-key-3', 'M3', 60); 60 | 61 | $this->assertEquals('M1', $memcache->get('multi-key-1')); 62 | $this->assertEquals('M2', $memcache->get('multi-key-2')); 63 | $this->assertEquals('M3', $memcache->get('multi-key-3')); 64 | } 65 | 66 | public function testMultiMemcacheInstanceUnformer() 67 | { 68 | $config = array( 69 | 'host' => '127.0.0.1, 127.0.0.1', 70 | 'port' => '11211, 11212', // same as 11211, 11212 71 | 'weight' => '20', // same as 20, 0 72 | ); 73 | 74 | $memcache = new PhalApi_Cache_Memcached($config); 75 | 76 | $memcache->set('multi-key-4', 'M4', 60); 77 | $this->assertEquals('M4', $memcache->get('multi-key-4')); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /Library/Qiniu/qiniu/auth_digest.php: -------------------------------------------------------------------------------- 1 | AccessKey = $accessKey; 16 | $this->SecretKey = $secretKey; 17 | } 18 | 19 | public function Sign($data) // => $token 20 | { 21 | $sign = hash_hmac('sha1', $data, $this->SecretKey, true); 22 | return $this->AccessKey . ':' . Qiniu_Encode($sign); 23 | } 24 | 25 | public function SignWithData($data) // => $token 26 | { 27 | $data = Qiniu_Encode($data); 28 | return $this->Sign($data) . ':' . $data; 29 | } 30 | 31 | public function SignRequest($req, $incbody) // => ($token, $error) 32 | { 33 | $url = $req->URL; 34 | $url = parse_url($url['path']); 35 | $data = ''; 36 | if (isset($url['path'])) { 37 | $data = $url['path']; 38 | } 39 | if (isset($url['query'])) { 40 | $data .= '?' . $url['query']; 41 | } 42 | $data .= "\n"; 43 | 44 | if ($incbody) { 45 | $data .= $req->Body; 46 | } 47 | return $this->Sign($data); 48 | } 49 | 50 | public function VerifyCallback($auth, $url, $body) // ==> bool 51 | { 52 | $url = parse_url($url); 53 | $data = ''; 54 | if (isset($url['path'])) { 55 | $data = $url['path']; 56 | } 57 | if (isset($url['query'])) { 58 | $data .= '?' . $url['query']; 59 | } 60 | $data .= "\n"; 61 | 62 | $data .= $body; 63 | $token = 'QBox ' . $this->Sign($data); 64 | return $auth === $token; 65 | } 66 | } 67 | 68 | function Qiniu_SetKeys($accessKey, $secretKey) 69 | { 70 | global $QINIU_ACCESS_KEY; 71 | global $QINIU_SECRET_KEY; 72 | 73 | $QINIU_ACCESS_KEY = $accessKey; 74 | $QINIU_SECRET_KEY = $secretKey; 75 | } 76 | 77 | function Qiniu_RequireMac($mac) // => $mac 78 | { 79 | if (isset($mac)) { 80 | return $mac; 81 | } 82 | 83 | global $QINIU_ACCESS_KEY; 84 | global $QINIU_SECRET_KEY; 85 | 86 | return new Qiniu_Mac($QINIU_ACCESS_KEY, $QINIU_SECRET_KEY); 87 | } 88 | 89 | function Qiniu_Sign($mac, $data) // => $token 90 | { 91 | return Qiniu_RequireMac($mac)->Sign($data); 92 | } 93 | 94 | function Qiniu_SignWithData($mac, $data) // => $token 95 | { 96 | return Qiniu_RequireMac($mac)->SignWithData($data); 97 | } 98 | 99 | // ---------------------------------------------------------- 100 | 101 | -------------------------------------------------------------------------------- /Library/Task/Task/Model/Task/TaskProgress.php: -------------------------------------------------------------------------------- 1 | getORM() 18 | ->select('id, title') 19 | ->where('state != ?', self::STATE_WAITTING) 20 | ->where('last_fire_time < ?', $maxLastFireTime) 21 | ->where('enable = ?', self::ENABLE_ON) 22 | ->order('last_fire_time ASC') 23 | ->fetchAll(); 24 | 25 | return !empty($rows) ? $rows : array(); 26 | } 27 | 28 | public function resetWrongItems($id) { 29 | return $this->update($id, array('state' => self::STATE_WAITTING)); 30 | } 31 | 32 | public function getAllWaittingItems() { 33 | $rows = $this->getORM() 34 | ->select('id, title, trigger_class, fire_params') 35 | ->where('state', self::STATE_WAITTING) 36 | ->where('interval_time + last_fire_time < ?', $_SERVER['REQUEST_TIME']) 37 | ->where('enable = ?', self::ENABLE_ON) 38 | ->fetchAll(); 39 | 40 | return !empty($rows) ? $rows : array(); 41 | } 42 | 43 | public function isRunnable($id) { 44 | $row = $this->get($id, 'enable, state'); 45 | 46 | if (empty($row)) { 47 | return FALSE; 48 | } 49 | 50 | return ($row['state'] == self::STATE_WAITTING && $row['enable'] == self::ENABLE_ON) ? TRUE : FALSE; 51 | } 52 | 53 | public function setRunningState($id) { 54 | return $this->update($id, array('state' => self::STATE_RUNNING)); 55 | } 56 | 57 | public function updateFinishItem($id, $result) { 58 | $data = array( 59 | 'result' => json_encode($result), 60 | 'state' => self::STATE_WAITTING, 61 | 'last_fire_time' => $_SERVER['REQUEST_TIME'], 62 | ); 63 | 64 | return $this->update($id, $data); 65 | } 66 | 67 | public function updateExceptionItem($id, $errorMsg) { 68 | $data = array( 69 | 'result' => $errorMsg, 70 | 'state' => self::STATE_EXCEPTION, 71 | 'last_fire_time' => $_SERVER['REQUEST_TIME'], 72 | ); 73 | 74 | return $this->update($id, $data); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /PhalApi/Tests/Cache/PhalApi_Cache_File_Test.php: -------------------------------------------------------------------------------- 1 | phalApiCacheFile = new PhalApi_Cache_File($config); 28 | } 29 | 30 | protected function tearDown() 31 | { 32 | } 33 | 34 | 35 | /** 36 | * @group testSet 37 | */ 38 | public function testSet() 39 | { 40 | $key = 'aYearKey'; 41 | $value = 2015; 42 | $expire = '200'; 43 | 44 | $rs = $this->phalApiCacheFile->set($key, $value, $expire); 45 | } 46 | 47 | /** 48 | * @group testGet 49 | * @depends testSet 50 | */ 51 | public function testGet() 52 | { 53 | $key = 'aYearKey'; 54 | 55 | $rs = $this->phalApiCacheFile->get($key); 56 | 57 | $this->assertSame(2015, $rs); 58 | } 59 | 60 | /** 61 | * @group testDelete 62 | * @depends testSet 63 | */ 64 | public function testDelete() 65 | { 66 | $key = 'aYearKey'; 67 | 68 | $this->phalApiCacheFile->delete($key); 69 | 70 | $rs = $this->phalApiCacheFile->get($key); 71 | 72 | $this->assertSame(NULL, $rs); 73 | } 74 | 75 | public function testGetAfterSet() 76 | { 77 | $key = 'anotherKey'; 78 | 79 | $value = array('name' => 'dogstar'); 80 | 81 | $this->phalApiCacheFile->set($key, $value); 82 | 83 | $this->assertSame($value, $this->phalApiCacheFile->get($key)); 84 | } 85 | 86 | public function testExpire() 87 | { 88 | $key = 'tmpKey'; 89 | $value = 'somethinghere~'; 90 | $expire = 2; 91 | 92 | $this->phalApiCacheFile->set($key, $value, $expire); 93 | 94 | $this->assertSame($value, $this->phalApiCacheFile->get($key)); 95 | 96 | sleep(3); 97 | 98 | $this->assertSame(NULL, $this->phalApiCacheFile->get($key)); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /PhalApi/Tests/PhalApi_Translator_Test.php: -------------------------------------------------------------------------------- 1 | coreTranslator = new PhalApi_Translator(); 25 | } 26 | 27 | protected function tearDown() 28 | { 29 | } 30 | 31 | 32 | /** 33 | * @group testGet 34 | */ 35 | public function testGet() 36 | { 37 | PhalApi_Translator::setLanguage('zh_cn'); 38 | 39 | $this->assertEquals('用户不存在', PhalApi_Translator::get('user not exists')); 40 | 41 | $this->assertEquals('PHPUnit您好,欢迎使用PhalApi!', PhalApi_Translator::get('Hello {name}, Welcome to use PhalApi!', array('name' => 'PHPUnit'))); 42 | 43 | $this->assertEquals('PhalApi 我爱你', T('{0} I love you', array('PhalApi'))); 44 | $this->assertEquals('PhalApi 我爱你因为no reasons', T('{0} I love you because {1}', array('PhalApi', 'no reasons'))); 45 | } 46 | 47 | /** 48 | * @group testSetLanguage 49 | */ 50 | public function testSetLanguage() 51 | { 52 | $language = 'en'; 53 | 54 | $rs = PhalApi_Translator::setLanguage($language); 55 | } 56 | 57 | /** 58 | * @group testFormatVar 59 | */ 60 | public function testFormatVar() 61 | { 62 | $name = 'abc'; 63 | 64 | $rs = PhalApi_Translator::formatVar($name); 65 | 66 | $this->assertEquals('{abc}', $rs); 67 | } 68 | 69 | public function testAddMessage() 70 | { 71 | PhalApi_Translator::setLanguage('zh_cn'); 72 | PhalApi_Translator::addMessage(dirname(__FILE__) . '/Data'); 73 | 74 | $this->assertEquals('this is a good way', PhalApi_Translator::get('test')); 75 | } 76 | 77 | public function testGetWithNoLanguageSet() 78 | { 79 | PhalApi_Translator_Mock::setLanguageNameSimple(null); 80 | 81 | $rs = T('test'); 82 | 83 | PhalApi_Translator::setLanguage('zh_cn'); 84 | } 85 | } 86 | 87 | class PhalApi_Translator_Mock extends PhalApi_Translator { 88 | 89 | public static function setLanguageNameSimple($lan) { 90 | PhalApi_Translator::$message = null; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /PhalApi/PhalApi/Request/Formatter/Base.php: -------------------------------------------------------------------------------- 1 | 2015-11-07 11 | */ 12 | 13 | 14 | class PhalApi_Request_Formatter_Base { 15 | 16 | /** 17 | * 根据范围进行控制 18 | */ 19 | protected function filterByRange($value, $rule) { 20 | $this->filterRangeMinLessThanOrEqualsMax($rule); 21 | 22 | $this->filterRangeCheckMin($value, $rule); 23 | 24 | $this->filterRangeCheckMax($value, $rule); 25 | 26 | return $value; 27 | } 28 | 29 | protected function filterRangeMinLessThanOrEqualsMax($rule) { 30 | if (isset($rule['min']) && isset($rule['max']) && $rule['min'] > $rule['max']) { 31 | throw new PhalApi_Exception_InternalServerError( 32 | T('min should <= max, but now {name} min = {min} and max = {max}', 33 | array('name' => $rule['name'], 'min' => $rule['min'], 'max' => $rule['max'])) 34 | ); 35 | } 36 | } 37 | 38 | protected function filterRangeCheckMin($value, $rule) { 39 | if (isset($rule['min']) && $value < $rule['min']) { 40 | throw new PhalApi_Exception_BadRequest( 41 | T('{name} should >= {min}, but now {name} = {value}', 42 | array('name' => $rule['name'], 'min' => $rule['min'], 'value' => $value)) 43 | ); 44 | } 45 | } 46 | 47 | protected function filterRangeCheckMax($value, $rule) { 48 | if (isset($rule['max']) && $value > $rule['max']) { 49 | throw new PhalApi_Exception_BadRequest( 50 | T('{name} should <= {max}, but now {name} = {value}', 51 | array('name' => $rule['name'], 'max' => $rule['max'], 'value' => $value)) 52 | ); 53 | } 54 | } 55 | 56 | /** 57 | * 格式化枚举类型 58 | * @param string $value 变量值 59 | * @param array $rule array('name' => '', 'type' => 'enum', 'default' => '', 'range' => array(...)) 60 | * @throws PhalApi_Exception_BadRequest 61 | */ 62 | protected function formatEnumValue($value, $rule) { 63 | if (!in_array($value, $rule['range'])) { 64 | throw new PhalApi_Exception_BadRequest( 65 | T('{name} should be in {range}, but now {name} = {value}', 66 | array('name' => $rule['name'], 'range' => implode('/', $rule['range']), 'value' => $value)) 67 | ); 68 | } 69 | } 70 | } 71 | --------------------------------------------------------------------------------