├── assets └── bryss.png ├── .gitignore ├── public ├── .htaccess └── index.php ├── Bryss ├── Interfaces │ ├── IResponse.php │ └── IRequest.php ├── App.php ├── Routing │ ├── Response.php │ ├── Request.php │ └── Router.php ├── Database.php ├── Utils.php └── Validator.php ├── composer.json ├── CONTRIBUTION.md ├── CODE_OF_CONDUCT.md ├── LICENSE.md └── README.md /assets/bryss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CITGuru/bryss/HEAD/assets/bryss.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .phpunit.result.cache 4 | composer.lock 5 | phpunit.xml 6 | clover.xml 7 | vendor 8 | coverage -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | RewriteEngine on 2 | RewriteCond %{REQUEST_FILENAME} !-f 3 | RewriteCond %{REQUEST_FILENAME} !-d 4 | RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA] -------------------------------------------------------------------------------- /Bryss/Interfaces/IResponse.php: -------------------------------------------------------------------------------- 1 | =5.3.0" 15 | }, 16 | "autoload": { 17 | "psr-4": { 18 | "Bryss\\": "Bryss" 19 | } 20 | }, 21 | "repositories": [ 22 | { 23 | "type": "vcs", 24 | "url": "https://github.com/CITGuru/bryss" 25 | } 26 | ], 27 | "license": "MIT" 28 | } 29 | -------------------------------------------------------------------------------- /CONTRIBUTION.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | ## Pull Requests 4 | 5 | 1. Fork the Bryss Framework repository 6 | 2. Create a new branch for each feature or improvement 7 | 3. Send a pull request from each feature branch to the dev branch 8 | 9 | It is very important to separate new features or improvements into separate feature branches, and to send a 10 | pull request for each branch. This allows me to review and pull in new features or improvements individually. 11 | 12 | ## Style Guide 13 | 14 | All pull requests must adhere to the [PSR-12 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md). 15 | 16 | ## Unit Testing 17 | 18 | I have not implemented the testing yet, still getting used to PHPUnit. Once testing has been implemented, all pull requests must be accompanied by passing unit tests and complete code coverage. I'll be using PHPUnit for the testing. 19 | 20 | [Learn about PHPUnit](https://github.com/sebastianbergmann/phpunit/) 21 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | The BryssFramework code of conduct is derived from the Ruby code of conduct. This document provides community guidelines for a safe, respectful, productive, and collaborative place for any person who is willing to contribute to the Bryss Framework community. It applies to all “collaborative space”, which is defined as community communications channels (such as mailing lists, IRC, Slack, forums, submitted patches, commit comments, etc.). Any violations of the code of conduct may be reported by contacting one or more of the project maintainers either directly or via email to me oyetoketoby80@gmail.com. 4 | 5 | * Participants will be tolerant of opposing views. 6 | * Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks. 7 | * When interpreting the words and actions of others, participants should always assume good intentions. 8 | * Behaviour that the project maintainers consider to be harassment will not be tolerated. -------------------------------------------------------------------------------- /Bryss/App.php: -------------------------------------------------------------------------------- 1 | router = $router; 26 | } 27 | 28 | public function set($name, $value){ 29 | $this->store{$name} = $value; 30 | } 31 | 32 | public function get($name, $default){ 33 | $value = $this->store{$name}; 34 | if($value){ 35 | return $value; 36 | } 37 | return $default; 38 | } 39 | 40 | static function create(){ 41 | $router = new Router(new Request, new Response); 42 | return $router; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Bryss/Routing/Response.php: -------------------------------------------------------------------------------- 1 | '); 42 | array_walk_recursive($body, array($Xml, 'addChild')); 43 | return $Xml->asXml(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Oyetoke Toby 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | get("/hello", function($req, $res, $args){ 15 | return $res->json(array( 16 | "message"=>"Hello World", 17 | "author" => "Oyetoke Tobi" 18 | )); 19 | }); 20 | 21 | $app->get('/hello-xml', function($req, $res, $args) { 22 | return $res->xml(array( 23 | "message" => "Hello World", 24 | "author" => "Ilori Stephen A " 25 | )); 26 | }); 27 | 28 | $app->get("/hello/:name", function($req, $res, $args){ 29 | $name = $req->params["name"]; 30 | return $res->json(array( 31 | "message"=>"Hello, ".$name 32 | )); 33 | }); 34 | 35 | // Post endpoint with validation 36 | 37 | $app->post('/api/v1/register', function($req, $res){ 38 | $body = $req->getBody(); 39 | $email = $req->input("email"); 40 | $password = $req->input("password"); 41 | $name = $req->input("name"); 42 | $role = $req->input("role", "user"); 43 | 44 | $validator = InputValidator::schema($body, array( 45 | "email"=>"required|email", 46 | "password"=>"required|min:8", 47 | "name"=>"required|min:2", 48 | )); 49 | 50 | if(count($validator)!=0){ 51 | return $req->json(array( 52 | "status"=>"error", 53 | "message"=>"Validation error", 54 | "errors"=>$validator 55 | ), 400); 56 | } 57 | 58 | return $res->json(array( 59 | "status"=>"success", 60 | "message"=>"Registration successfull", 61 | "data"=>$body 62 | ), 200); 63 | 64 | }); 65 | 66 | $app->put("/api/v1/user", function($req, $res){ 67 | return $res->json(array( 68 | "message"=>"PUT method" 69 | )); 70 | }); 71 | 72 | $app->delete("/api/v1/user", function($req, $res){ 73 | return $res->json(array( 74 | "message"=>"DELETE method" 75 | )); 76 | }); 77 | -------------------------------------------------------------------------------- /Bryss/Database.php: -------------------------------------------------------------------------------- 1 | host = $host; 19 | $this->username = $username; 20 | $this->password = $password; 21 | $this->database = $database; 22 | 23 | $conn = $this->getConnection(); 24 | 25 | return $conn; 26 | } 27 | 28 | // get the database connection 29 | public function getConnection(){ 30 | 31 | $this->connection = null; 32 | 33 | try{ 34 | $this->connection = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->database, $this->username, $this->password); 35 | $this->connection->exec("set names utf8"); 36 | }catch(PDOException $exception){ 37 | echo "Error: " . $exception->getMessage(); 38 | } 39 | 40 | return $this->connection; 41 | } 42 | 43 | public function query($query, $data=array()){ 44 | $prep = $this->connection->prepare($query); 45 | $prep->execute($data); 46 | $result = $prep->fetchAll(PDO::FETCH_ASSOC); 47 | return $result; 48 | } 49 | 50 | public function queryFirstRow($query, $data=array()){ 51 | $prep = $this->connection->prepare($query); 52 | $prep->execute($data); 53 | $result = $prep->fetch(PDO::FETCH_ASSOC); 54 | return $result; 55 | } 56 | 57 | public function queryFirstField($query, $data=array()){ 58 | $result = $this->queryFirstRow($query, $data); 59 | if($result){ 60 | return array_values($result)[0]; 61 | } 62 | return $result; 63 | } 64 | 65 | public function sanitizeSQL($qs){ 66 | return mysql_real_escape_string($qs); 67 | } 68 | 69 | public function queryDB($query){ 70 | $prep = $this->connection->query($query); 71 | $result = $prep->fetchAll(PDO::FETCH_ASSOC); 72 | return $result; 73 | } 74 | } -------------------------------------------------------------------------------- /Bryss/Routing/Request.php: -------------------------------------------------------------------------------- 1 | bootstrapSelf(); 14 | } 15 | 16 | private function bootstrapSelf() 17 | { 18 | foreach($_SERVER as $key => $value) 19 | { 20 | $this->{$this->toCamelCase($key)} = $value; 21 | } 22 | 23 | } 24 | 25 | private function toCamelCase($string) 26 | { 27 | $result = strtolower($string); 28 | 29 | preg_match_all('/_[a-z]/', $result, $matches); 30 | 31 | foreach($matches[0] as $match) 32 | { 33 | $c = str_replace('_', '', strtoupper($match)); 34 | $result = str_replace($match, $c, $result); 35 | } 36 | 37 | return $result; 38 | } 39 | 40 | public function getBody() 41 | { 42 | if($this->requestMethod === "GET") 43 | { 44 | return; 45 | } 46 | 47 | $postMethods = ["POST", "PUT", "DELETE"]; 48 | 49 | if (in_array($this->requestMethod, $postMethods)) 50 | { 51 | $_POST = json_decode(file_get_contents('php://input'), true); 52 | 53 | 54 | // $body = array(); 55 | // foreach($_POST as $key => $value) 56 | // { 57 | // $body[$key] = filter_input(INPUT_POST, $key, FILTER_SANITIZE_SPECIAL_CHARS); 58 | // } 59 | 60 | return $_POST; 61 | } 62 | } 63 | 64 | public function getHeader(){ 65 | $header = getallheaders(); 66 | return $header; 67 | } 68 | 69 | public function input($key, $default=NULL) 70 | { 71 | $body = $this->getBody(); 72 | $data = $body[$key]; 73 | if(!$data){ 74 | return $default; 75 | } 76 | return $data; 77 | } 78 | 79 | 80 | public function header($key, $default=NULL) 81 | { 82 | $header = $this->getHeader(); 83 | $data = $header[$key]; 84 | if(!$data){ 85 | return $default; 86 | } 87 | return $data; 88 | } 89 | 90 | public function json($body, $status=200) 91 | { 92 | header('HTTP/1.1 '.$status.''); 93 | header('Content-type: application/json'); 94 | 95 | return json_encode($body); 96 | 97 | } 98 | 99 | public function html($body, $data) 100 | { 101 | 102 | 103 | 104 | return json_encode($body); 105 | 106 | } 107 | } -------------------------------------------------------------------------------- /Bryss/Utils.php: -------------------------------------------------------------------------------- 1 | $value){ 29 | $requestHeaders[] = $key.": ".$value; 30 | } 31 | 32 | $ch = curl_init(); 33 | 34 | curl_setopt_array($ch, array( 35 | CURLOPT_URL => $url, 36 | CURLOPT_RETURNTRANSFER => true, 37 | CURLOPT_ENCODING => "", 38 | CURLOPT_MAXREDIRS => 10, 39 | CURLOPT_TIMEOUT => 0, 40 | CURLOPT_FOLLOWLOCATION => true, 41 | CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, 42 | CURLOPT_CUSTOMREQUEST => "GET", 43 | CURLOPT_HTTPHEADER => $requestHeaders, 44 | )); 45 | 46 | $response = curl_exec($ch); 47 | 48 | // curl_close($ch); 49 | 50 | $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 51 | 52 | $err = curl_error($ch); 53 | 54 | curl_close($ch); 55 | $res = json_decode($response); 56 | if ($err){ 57 | ### failed 58 | return array("status"=>false, "httpcode"=> 500, "message"=>json_encode(array("error"=>$err))); 59 | }else{ 60 | switch ($httpcode){ 61 | case 201: 62 | case 200: # OK 63 | // echo $res; 64 | return array("status"=>true,"message"=>$res,"httpcode"=>$httpcode); 65 | break; 66 | default: 67 | return array("status"=>false,"message"=>$res,"httpcode"=>$httpcode); 68 | } 69 | } 70 | } 71 | function httpPost($url, $body=array(), $headers=array()){ 72 | 73 | $requestHeaders = array(); 74 | $requestHeaders[] = 'Content-type: application/json'; 75 | 76 | foreach($headers as $key => $value){ 77 | $requestHeaders[] = $key.": ".$value; 78 | } 79 | 80 | 81 | $ch = curl_init($url); 82 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 83 | curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); 84 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); 85 | $response = curl_exec($ch); 86 | $res = json_decode($response); 87 | 88 | $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 89 | 90 | $err = curl_error($ch); 91 | 92 | curl_close($ch); 93 | 94 | if ($err){ 95 | ### failed 96 | return array("status"=>false,"message"=>json_encode(array("error"=>$err))); 97 | }else{ 98 | switch ($httpcode){ 99 | case 200: 100 | case 201: # OK 101 | 102 | return array("status"=>true,"message"=>$res,"httpcode"=>$httpcode); 103 | break; 104 | default: 105 | return array("status"=>false,"message"=>$res,"httpcode"=>$httpcode); 106 | } 107 | } 108 | 109 | } 110 | 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bryss Framework 2 | 3 | ![Bryss](assets/bryss.png) 4 | 5 | Bryss is a PHP micro framework that helps you quickly write simple yet powerful RESTful APIs inspired by Express and Slim (read the source code by heart). Bryss is built from ground up and no dependencies used currently. 6 | 7 | * This is still in its early development used with care * 8 | 9 | ## Installation 10 | 11 | It's recommended that you use [Composer](https://getcomposer.org/) to install Bryss. 12 | 13 | ```bash 14 | $ composer require citguru/bryss:dev-master 15 | ``` 16 | *This project is still in development and no stable version yet. You can install by using the :dev-master tag. You should be able to install without it once there's a stable release* 17 | 18 | This will install Bryss. Bryss have supports for PHP version from 5.3.0 to the latest ones. 19 | 20 | You can also clone this repo directly to your project folder and require the needed classes. 21 | 22 | 23 | ## Usage 24 | 25 | Simple HelloWorld impelmentation of Bryss Framework. 26 | 27 | ```php 28 | get("/hello", function($req, $res){ 40 | return $res->json(array( 41 | "message"=>"Hello World" 42 | )); 43 | }); 44 | 45 | $app->get('/hello-xml', function($req, $res, $args) { 46 | return $res->xml(array( 47 | "message" => "Hello World", 48 | "author" => "Ilori Stephen A " 49 | )); 50 | }); 51 | 52 | $app->get("/hello/:name", function($req, $res){ 53 | $name = $req->params["name"]; 54 | return $res->json(array( 55 | "message"=>"Hello World, ".$name 56 | ), 201); 57 | }); 58 | ?> 59 | ``` 60 | 61 | You can quickly test this using the built-in PHP server: 62 | 63 | ```bash 64 | $ php -S localhost:8000 -t public 65 | ``` 66 | 67 | Going to http://localhost:8000/hello/, http://localhost:8000/hello-xml/ or http://localhost:8000/hello/:name would return: 68 | 69 | ```json 70 | { 71 | "message": "Hello World" 72 | } 73 | ``` 74 | 75 | ```xml 76 | 77 | Hello World 78 | Ilori Stephen A 79 | 80 | ``` 81 | 82 | ```json 83 | { 84 | "message": "Hello World, " 85 | } 86 | ``` 87 | 88 | ## Deployment 89 | 90 | If you have Apache/Nginx and PHP setup either on your own server or shared hosting, you can easily use `.htaccess` to route all requests to an entry file which is usually `index.php`. 91 | 92 | ``` 93 | RewriteEngine on 94 | RewriteCond %{REQUEST_FILENAME} !-f 95 | RewriteCond %{REQUEST_FILENAME} !-d 96 | RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA] 97 | ``` 98 | 99 | or 100 | 101 | ``` 102 | 103 | RewriteEngine on 104 | RewriteRule ^$ public/ [L] 105 | RewriteRule (^[^/]*$) public/$1 [L] 106 | 107 | ``` 108 | 109 | This means you would need to upload your Bryss project and all other files to the `public` or any folder you want (you will need to switch it out in the htaccess) to use. You will probably use FTP to upload it. 110 | 111 | ## Documentation 112 | 113 | Coming soon... For the main time kindly check [public/index](public/index.php) for how to use it. 114 | 115 | ## Contributions 116 | 117 | Please see [CONTRIBUTION](CONTRIBUTION.md) for details. 118 | 119 | ## Security 120 | 121 | If you discover security related issues, please email me : oyetoketoby80@gmail.com 122 | 123 | ## License 124 | 125 | Copyright (c) 2020 Oyetoke Toby (twitter: @oyetokeT) 126 | 127 | The Bryss Framework is licensed under the MIT license. See [License File](LICENSE.md) for more information. 128 | -------------------------------------------------------------------------------- /Bryss/Validator.php: -------------------------------------------------------------------------------- 1 | $length){ 29 | return self::throwError("Maximum length of value reached. Value length must be less than $length", 901); 30 | } 31 | return $val; 32 | } 33 | 34 | static function min($val, $length){ 35 | $val_len = strlen($val); 36 | if($val_len<$length){ 37 | return self::throwError("Minimum length of value reached. Value length must be greater than $length", 901); 38 | } 39 | return $val; 40 | } 41 | 42 | static function len($val, $length){ 43 | $val_len = strlen($val); 44 | if($val_len!=$length){ 45 | return self::throwError("Value length must be equal to $length", 901); 46 | } 47 | return $val; 48 | } 49 | 50 | static function int($val) { 51 | $val = filter_var($val, FILTER_VALIDATE_INT); 52 | if ($val === false) { 53 | return self::throwError('Invalid Integer', 901); 54 | } 55 | return $val; 56 | } 57 | 58 | static function str($val) { 59 | if (!is_string($val)) { 60 | return self::throwError('Invalid String', 902); 61 | } 62 | $val = trim(htmlspecialchars($val)); 63 | return $val; 64 | } 65 | 66 | static function bool($val) { 67 | $val = filter_var($val, FILTER_VALIDATE_BOOLEAN); 68 | return $val; 69 | } 70 | 71 | static function email($val) { 72 | $val = filter_var($val, FILTER_VALIDATE_EMAIL); 73 | if ($val === false) { 74 | return self::throwError('Invalid Email', 903); 75 | } 76 | return $val; 77 | } 78 | 79 | static function url($val) { 80 | $val = filter_var($val, FILTER_VALIDATE_URL); 81 | if ($val === false) { 82 | return self::throwError('Invalid URL', 904); 83 | } 84 | return $val; 85 | } 86 | 87 | static function schema($data, $schema){ 88 | $checks = array( 89 | "required" =>"self::required", 90 | "email" =>"self::email", 91 | "min"=>"self::min", 92 | "max"=>"self::max", 93 | "str"=>"self::str", 94 | "int"=>"self::int", 95 | "bool"=>"self::bool", 96 | "url"=>"self::url", 97 | "len"=>"self::len", 98 | ); 99 | 100 | $errors=array(); 101 | foreach($schema as $sk => $sv){ 102 | $sv_match_split = explode("|", $sv); 103 | if(array_key_exists($sk, $data)){ 104 | $sk_data = $data[$sk]; 105 | 106 | foreach($sv_match_split as $sk_check){ 107 | $_sk_check_values = explode(":", $sk_check); 108 | if(count($_sk_check_values)==1){ 109 | $validate = call_user_func_array($checks[$_sk_check_values[0]], [$sk_data]); 110 | }else{ 111 | $validate = call_user_func_array($checks[$_sk_check_values[0]], [$sk_data, $_sk_check_values[1]]); 112 | } 113 | if(is_array($validate) && $validate["valid"]==false){ 114 | array_push($errors, array( 115 | "field"=>$sk, 116 | "message"=>$validate["data"]["message"] 117 | )); 118 | } 119 | } 120 | }else{ 121 | if(in_array("required", $sv_match_split)) 122 | { 123 | array_push($errors, array( 124 | "field"=>$sk, 125 | "message"=>"Field is required. Data is missing." 126 | )); 127 | } 128 | 129 | } 130 | } 131 | return $errors; 132 | } 133 | 134 | static function throwError($error = 'Error In Processing', $errorCode = 0) { 135 | if (self::$errors === true) { 136 | return array( 137 | "valid"=>false, 138 | "data"=>array( 139 | "message"=>$error, 140 | "code"=>$errorCode 141 | )); 142 | 143 | } 144 | } 145 | 146 | } 147 | -------------------------------------------------------------------------------- /Bryss/Routing/Router.php: -------------------------------------------------------------------------------- 1 | request = $request; 25 | $this->response = $response; 26 | 27 | } 28 | 29 | function __call($name, $args) 30 | { 31 | list($route, $method) = $args; 32 | 33 | if(!in_array(strtoupper($name), $this->supportedHttpMethods)) 34 | { 35 | $this->invalidMethodHandler(); 36 | } 37 | $this->{strtolower($name)}[$this->formatRoute($route)] = $method; 38 | } 39 | 40 | /** 41 | * Removes trailing forward slashes from the right of the route. 42 | * @param route (string) 43 | */ 44 | private function formatRoute($route) 45 | { 46 | $result = rtrim($route, '/'); 47 | if ($result === '') 48 | { 49 | return '/'; 50 | } 51 | return $result; 52 | } 53 | 54 | private function startsWith ($string, $startString) 55 | { 56 | $len = strlen($startString); 57 | return (substr($string, 0, $len) === $startString); 58 | } 59 | 60 | // 405 method not allowed handler 61 | 62 | private function invalidMethodHandler() 63 | { 64 | header("{$this->request->serverProtocol} 405 Method Not Allowed"); 65 | header('Content-type: application/json'); 66 | echo json_encode(array("status"=>"405", "message"=>"Method Not Allowed")); 67 | return; 68 | 69 | } 70 | 71 | // 500 server error handler 72 | 73 | private function serverErrorHandler($e) 74 | { 75 | header("{$this->request->serverProtocol} 500 Server Error"); 76 | header('Content-type: application/json'); 77 | echo json_encode(array("status"=>"500", "message"=>"An unknown error occured while trying to perform an operation", "error"=>$e)); 78 | return; 79 | 80 | } 81 | 82 | // Default 404 request handler for unknown routess 83 | 84 | private function defaultRequestHandler() 85 | { 86 | header("{$this->request->serverProtocol} 404 Not Found"); 87 | header('Content-type: application/json'); 88 | 89 | echo json_encode(array("status"=>"404", "message"=>"Not Found")); 90 | return; 91 | } 92 | 93 | /** 94 | * Resolves a route 95 | */ 96 | function resolve() 97 | { 98 | 99 | $queries = array(); 100 | parse_str($this->request->queryString, $queries); 101 | $args = array( 102 | "params"=> array(), 103 | "queries"=>$queries 104 | ); 105 | 106 | $methodDictionary = $this->{strtolower($this->request->requestMethod)}; 107 | 108 | // Double check resource path uri 109 | 110 | $path = $this->request->pathInfo; 111 | if(!$path){ 112 | $path = $this->request->requestUri; 113 | } 114 | $formatedRoute = $this->formatRoute($path); 115 | 116 | 117 | if($methodDictionary && array_key_exists($formatedRoute, $methodDictionary)){ 118 | $method = $methodDictionary[$formatedRoute]; 119 | 120 | }else{ 121 | // Match path with params - :paramName 122 | // Finding a more smarter way 123 | $path = $this->formatRoute($path); 124 | if($methodDictionary){ 125 | foreach($methodDictionary as $k => $v){ 126 | if(strpos($k,":") !==false){ 127 | $pathSplit = explode("/", $path); 128 | $currentPathSplit = explode("/", $k); 129 | $pathCount = count($pathSplit); 130 | if($pathCount == count($currentPathSplit)){ 131 | $equalCount = 0; 132 | $pathParams = array(); 133 | for ($x = 0; $x < $pathCount; $x++) { 134 | if($pathSplit[$x] == $currentPathSplit[$x]){ 135 | $equalCount++; 136 | }elseif($this->startsWith($currentPathSplit[$x], ":")){ 137 | $equalCount++; 138 | $paramKey = substr($currentPathSplit[$x], 1); 139 | $pathParams[$paramKey] = $pathSplit[$x]; 140 | } 141 | } 142 | if($equalCount==$pathCount){ 143 | $method = $v; 144 | $args["params"] = $pathParams; 145 | break; 146 | } 147 | } 148 | } 149 | } 150 | } 151 | 152 | 153 | } 154 | 155 | if(is_null($method)) 156 | { 157 | 158 | $this->defaultRequestHandler(); 159 | return; 160 | } 161 | 162 | $this->request->params = $args["params"]; 163 | $this->request->queries = $args["queries"]; 164 | $this->request->body = $this->request->getBody(); 165 | $this->request->headers = $this->request->getHeader(); 166 | $this->request->path = $path; 167 | 168 | echo call_user_func_array($method, array($this->request, $this->response, $args)); 169 | 170 | } 171 | 172 | function __destruct() 173 | { 174 | $this->resolve(); 175 | } 176 | } --------------------------------------------------------------------------------