├── .gitignore ├── .htaccess ├── App ├── .htaccess ├── Controllers │ └── HomeController.php ├── Core │ └── MyController.php ├── Models │ └── TestModel.php ├── Router.php └── Views │ ├── index.php │ └── test.edge.php ├── Public └── index.html ├── README.md ├── System ├── .htaccess ├── Core │ ├── App.php │ ├── Autoload.php │ ├── Controller.php │ ├── Model.php │ └── Route.php ├── Helpers │ ├── Session.php │ └── Template.php └── Plugins │ └── Setting.php ├── composer.json ├── config.php └── index.php /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .idea 3 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | Options -Indexes 2 | Options -MultiViews 3 | RewriteEngine On 4 | 5 | RewriteCond %{REQUEST_FILENAME} !-d 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteRule ^(.+)$ index.php?url=$1 [QSA,L] -------------------------------------------------------------------------------- /App/.htaccess: -------------------------------------------------------------------------------- 1 | #deny all access 2 | deny from all -------------------------------------------------------------------------------- /App/Controllers/HomeController.php: -------------------------------------------------------------------------------- 1 | loadTemplate("test",["deneme"=>"Emre"]); 11 | 12 | 13 | $this->loadView("index"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /App/Core/MyController.php: -------------------------------------------------------------------------------- 1 | '; 9 | } 10 | 11 | function __destruct(){ 12 | echo '
Core Controller Destruct'; 13 | } 14 | } -------------------------------------------------------------------------------- /App/Models/TestModel.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /App/Router.php: -------------------------------------------------------------------------------- 1 | name("ana"); 9 | $ana->where("baslik","[a-zA-Z0-9-]+"); 10 | */ 11 | 12 | Route::any("iletisim{/}","Home@index"); 13 | 14 | Route::get("deneme/{method}/{baslik}","{1}@{2}"); 15 | 16 | Route::any("","Home@index"); -------------------------------------------------------------------------------- /App/Views/index.php: -------------------------------------------------------------------------------- 1 | index
-------------------------------------------------------------------------------- /App/Views/test.edge.php: -------------------------------------------------------------------------------- 1 | merhaba {{$deneme}}
-------------------------------------------------------------------------------- /Public/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eylmz/PHP-MVC/a010f160eb5c3ca1a329cb875c42e08dff8db291/Public/index.html -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP-MVC 2 | PHP-MVC, basit ve küçük çapta olan projeler için bir php web çatısıdır. SEO uyumlu linkleri destekler. 3 | 4 | #### Sürüm : 0.0.3 5 | ## Özellikler 6 | - MVC tasarım deseni yapısında. 7 | - Basit ve kullanımı kolay. 8 | - Kolay ve hızlıca rotalandırma. 9 | - Veritabanı işlemleri için, [Medoo](http://medoo.in/). 10 | - Tasarım moturu için, [Edge](https://github.com/ventoviro/windwalker-edge) 11 | 12 | ## Kurulum 13 | #### Composer 14 | ``` 15 | composer create-project eylmz/wd-mvc wd-mvc 16 | ``` 17 | ## Dizin Yapısı 18 | ``` 19 | PHP-MVC 20 | | .htaccess 21 | | index.php 22 | | 23 | +---App 24 | | | .htaccess 25 | | | Router.php 26 | | | 27 | | +---Config 28 | | | Config.php 29 | | | Database.php 30 | | | PrettyUrls.php 31 | | | 32 | | +---Controllers 33 | | | | HomeController.php 34 | | | | 35 | | | \---Admin 36 | | | AdminHomeController.php 37 | | | 38 | | +---Models 39 | | | TestModel.php 40 | | | YeniModel.php 41 | | | 42 | | \---Views 43 | | | index.php 44 | | | test.edge.php 45 | | | 46 | | \---AdminViews 47 | | index.php 48 | | 49 | +---Public 50 | | index.html 51 | | 52 | +---System 53 | | | .htaccess 54 | | | 55 | | +---Core 56 | | | App.php 57 | | | Autoload.php 58 | | | Controller.php 59 | | | Model.php 60 | | | Route.php 61 | | | Router.php 62 | | | 63 | | +---Helpers 64 | | | Session.php 65 | | | Template.php 66 | | | 67 | | \---Plugins 68 | Setting.php 69 | ``` 70 | -------------------------------------------------------------------------------- /System/.htaccess: -------------------------------------------------------------------------------- 1 | #deny all access 2 | deny from all -------------------------------------------------------------------------------- /System/Core/App.php: -------------------------------------------------------------------------------- 1 | {$fileName}' dosyası bulunamadı!"); 25 | } 26 | } 27 | 28 | Autoload::register(); -------------------------------------------------------------------------------- /System/Core/Controller.php: -------------------------------------------------------------------------------- 1 | '.$fileName.' isimli dosya bulunamadı!'; 20 | } 21 | 22 | function loadTemplate($fileName,$data=array(),$returnHTML=false){ 23 | if(file_exists("App/Views/".$fileName.".edge.php")){ 24 | $template = new Template(); 25 | $render = $template->render($fileName,$data); 26 | if($returnHTML) 27 | return $render; 28 | echo $render; 29 | }else echo ''.$fileName.' isimli dosya bulunamadı!'; 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /System/Core/Model.php: -------------------------------------------------------------------------------- 1 | DB_CONNECTION, 16 | "database_name" => DB_DATABASE, 17 | "server" => DB_HOST, 18 | "port" => DB_PORT, 19 | "username" => DB_USERNAME, 20 | "password" => DB_PASSWORD, 21 | "charset" => DB_CHARSET 22 | ]; 23 | 24 | try 25 | { 26 | return self::$connection = new Medoo($db); 27 | } 28 | catch( Exception $e ) 29 | { 30 | exit($e->getMessage()); 31 | } 32 | } 33 | 34 | public function __construct() 35 | { 36 | $this->db = $this->connect();; 37 | } 38 | 39 | public function errorMessage(){ 40 | return $this->db->error()[2]; 41 | } 42 | 43 | public function lastQuery(){ 44 | return $this->db->last(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /System/Core/Route.php: -------------------------------------------------------------------------------- 1 | [], 9 | "GET" => [], 10 | "POST" => [], 11 | "PUT" => [], 12 | "PATCH" => [], 13 | "DELETE" => [], 14 | "OPTION" => [] 15 | ]; 16 | private static $prefix = []; 17 | private static $middlewares = []; 18 | private static $latestMethods = []; 19 | private static $groups = []; 20 | private static $names = []; 21 | 22 | private static $current = false; 23 | 24 | // Coming SoooooooooN 25 | private static $controllerNamespace = "App\\Controllers\\"; 26 | private static $controllerNamePostfix = "Controller"; 27 | private static $middlewareNamespace = "App\\Middlewares\\"; 28 | 29 | 30 | private function __construct(){} 31 | 32 | private static function getUrl($url){ 33 | return ltrim(urldecode($url),"/"); 34 | } 35 | 36 | private static function getRoutes(){ 37 | $routes = []; 38 | $method = self::getRequestMethod(); 39 | if(is_array(self::$routes["ANY"]) && is_array(self::$routes[$method])) 40 | $routes = array_merge(self::$routes["ANY"],self::$routes[$method]); 41 | return $routes; 42 | } 43 | 44 | private static function controlUrl($url,$rUrl,$where,&$parameters){ 45 | // O anki rotanın koşullarını düzelt 46 | if(count($where)){ 47 | foreach($where as $key=>$value){ 48 | $rUrl = preg_replace("@{".$key."}@","(".$value.")",$rUrl); 49 | $rUrl = preg_replace("@{".$key."\?}@","(".$value."|)",$rUrl); 50 | } 51 | } 52 | 53 | // Koşulsuz parametreleri her türlü veri alabilecek şekle getir 54 | $rUrl = preg_replace("@{([0-9a-zA-Z]+)}@","(.*?)",$rUrl); 55 | $rUrl = preg_replace("@{([0-9a-zA-Z]+)\?}@","(.*?|)",$rUrl); 56 | 57 | // Zorun olmayan slash işareti 58 | $rUrl = preg_replace("@{/}@","(/?)",$rUrl); 59 | 60 | // Rota ile tüm urlyi karşılaştır uymuyorsa atla 61 | $result = preg_match("@^".$rUrl."$@",$url,$parameters); 62 | unset($parameters[0]); 63 | $parameters = array_values($parameters); 64 | return $result; 65 | } 66 | 67 | private static function clearParameters(&$parameters,$values = []){ 68 | if(count($values)){ 69 | foreach ($values as $value) { 70 | unset($parameters[$value]); 71 | } 72 | $parameters = array_values($parameters); 73 | }else { 74 | for ($i = count($parameters); $i > 0; $i--) { 75 | if (isset($parameters[$i]) && ($parameters[$i] == "/" || !$parameters[$i])) { 76 | unset($parameters[$i]); 77 | } 78 | } 79 | $parameters = array_values($parameters); 80 | } 81 | } 82 | 83 | private static function getController($controller,&$parameters,&$unset){ 84 | // Controller rotadan parametresiz mi gelecek? 85 | if ($controller == "{?}") { 86 | if (isset($parameters[0])) { 87 | $controller = ucfirst(strtolower($parameters[0])); 88 | unset($parameters[0]); 89 | } else die("Controller parametresi bulunamadi!"); 90 | // Controller rotadan parametreli mi gelecek? 91 | } else if (preg_match("@{([0-9]+)}@", $controller, $cont)) { 92 | if (isset($parameters[$cont[1]])) { 93 | $controller = ucfirst(strtolower($parameters[$cont[1]])); 94 | $unset[] = $cont[1]; 95 | } else die("Controller parametresi bulunamadi!"); 96 | } 97 | $parameters = array_values($parameters); 98 | return "App\\Controllers\\" . $controller . "Controller"; 99 | } 100 | 101 | private static function getMethod($method,&$parameters,&$unset){ 102 | // Method rotadan parametresiz mi gelecek? 103 | if ($method == "{?}") { 104 | if (isset($parameters[0])) { 105 | $method = strtolower($parameters[0]); 106 | unset($parameters[0]); 107 | } else die("Method parametresi bulunamadi!"); 108 | // Method rotadan parametreli mi gelecek? 109 | } else if (preg_match("@{([0-9]+)}@", $method, $meth)) { 110 | if (isset($parameters[$meth[1]])) { 111 | $method = strtolower($parameters[$meth[1]]); 112 | $unset[] = $meth[1]; 113 | } else die("Method parametresi bulunamadi!"); 114 | } 115 | return $method; 116 | } 117 | 118 | private static function handleMiddleware($middlewares){ 119 | if(count($middlewares)) { 120 | foreach ($middlewares as $middleware) { 121 | $middleware = "App\\Middlewares\\" . $middleware; 122 | if (class_exists($middleware)) { 123 | if (method_exists($middleware, "handle")) { 124 | forward_static_call([$middleware, "handle"]); 125 | } 126 | } 127 | } 128 | } 129 | } 130 | 131 | private static function handleController($controller,&$parameters){ 132 | // Rotada çağrılan method string mi yoksa fonksiyon mu 133 | if(is_string($controller)) { 134 | // String rotada tanımlayabileceği şartlar 135 | if(preg_match("/^([{?}a-zA-Z0-9]+)@([{?}a-zA-Z0-9]+)$/",$controller,$result)){ 136 | // Hem controller hem de method kısmı alındı mı 137 | if(isset($result[1]) && isset($result[2])) { 138 | $unset = []; 139 | $controller = self::getController($result[1],$parameters,$unset); 140 | $method = self::getMethod($result[2],$parameters,$unset); 141 | 142 | // Controller ve method için kullanılan parametreler siliniyor 143 | self::clearParameters($parameters,$unset); 144 | 145 | // Controller var mı 146 | if (class_exists($controller)) { 147 | // Method var mı 148 | if (method_exists($controller, $method)) { 149 | $controller = new $controller(); 150 | $return = call_user_func_array([$controller,$method],$parameters); 151 | if(is_array($return)) 152 | echo json_encode($return); 153 | } else die("" . $controller . " isimli controllerin " . $method . " isimli methodu bulunamadi!"); 154 | } else die("" . $controller . " isimli controller bulunamadi!"); 155 | }else die("Router controller@method sorunu"); 156 | } 157 | // Rotada çağrılan method fonksiyonya çalıştır 158 | }else if(is_callable($controller)) { 159 | $return = call_user_func_array($controller, $parameters); 160 | if(is_array($return)) 161 | echo json_encode($return); 162 | } 163 | } 164 | 165 | private static function getRequestMethod(){ 166 | $method = $_SERVER['REQUEST_METHOD']; 167 | if($method == "POST") { 168 | $headers = []; 169 | foreach ($_SERVER as $name => $value) { 170 | if ((substr($name, 0, 5) == 'HTTP_') || ($name == 'CONTENT_TYPE') || ($name == 'CONTENT_LENGTH')) { 171 | $headers[str_replace([' ', 'Http'], ['-', 'HTTP'], ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; 172 | } 173 | } 174 | 175 | if (isset($headers['X-HTTP-Method-Override']) && in_array($headers['X-HTTP-Method-Override'], ['PUT', 'DELETE', 'PATCH', 'OPTION'])) { 176 | $method = $headers['X-HTTP-Method-Override']; 177 | } 178 | } 179 | return $method; 180 | } 181 | 182 | private static function setCurrent($name,$url,$pattern,$parameters,$method){ 183 | self::$current = [ 184 | "name" => $name, 185 | "url" => $url, 186 | "pattern" => $pattern, 187 | "parameters" => $parameters, 188 | "method" => $method 189 | ]; 190 | } 191 | 192 | static function routeNow(){ 193 | $method = @$_GET["url"]; 194 | $url = self::getUrl($method); 195 | $routes = self::getRoutes(); 196 | 197 | foreach($routes as $route){ 198 | $parameters = []; 199 | 200 | if(!self::controlUrl($url,$route["url"],$route["where"],$parameters)) 201 | continue; 202 | 203 | self::clearParameters($parameters); 204 | self::handleMiddleware($route["middleware"]); 205 | self::handleController($route["function"],$parameters); 206 | self::setCurrent($route["name"],$url,$route["url"],$parameters,$method); 207 | break; 208 | } 209 | } 210 | 211 | static function getInstance(){ 212 | if(self::$instance == null) 213 | self::$instance = new self; 214 | return self::$instance; 215 | } 216 | 217 | static function prefix($name){ 218 | $instance = self::getInstance(); 219 | array_push(self::$prefix,trim($name,"/")); 220 | return $instance; 221 | } 222 | 223 | static function middleware($middleware){ 224 | $instance = self::getInstance(); 225 | if(is_array($middleware)) 226 | self::$middlewares = $middleware; 227 | else 228 | self::$middlewares[] = $middleware; 229 | return $instance; 230 | } 231 | 232 | function group($callback){ 233 | array_push(self::$groups,1); 234 | call_user_func($callback); 235 | array_pop(self::$groups); 236 | array_pop(self::$prefix); 237 | } 238 | 239 | static function match($methods,$url,$function){ 240 | $instance = self::getInstance(); 241 | self::$latestMethods = []; 242 | 243 | if(!is_array($methods)) 244 | self::$latestMethods = explode("|",$methods); 245 | 246 | if(is_array(self::$latestMethods) && count(self::$latestMethods)) { 247 | foreach (self::$latestMethods as $method) { 248 | $middlewares = []; 249 | $url = trim($url, "/"); 250 | if(count(self::$groups)) { 251 | if (is_array(self::$middlewares)) { 252 | $middlewares = self::$middlewares; 253 | } 254 | 255 | if(count(self::$prefix)) { 256 | $prefix = implode("/", self::$prefix); 257 | $url = $prefix . "/" . $url; 258 | } 259 | } 260 | 261 | self::$routes[strtoupper($method)][] = [ 262 | "name" => "", 263 | "url" => $url, 264 | "function" => $function, 265 | "where" => null, 266 | "middleware" => $middlewares 267 | ]; 268 | } 269 | } 270 | return $instance; 271 | } 272 | 273 | static function any($url, $function){ 274 | return self::match("ANY",$url,$function); 275 | } 276 | 277 | static function get($url, $function){ 278 | return self::match("GET",$url,$function); 279 | } 280 | 281 | static function post($url, $function){ 282 | return self::match("POST",$url,$function); 283 | } 284 | 285 | static function put($url, $function){ 286 | return self::match("PUT",$url,$function); 287 | } 288 | 289 | static function patch($url, $function){ 290 | return self::match("PATCH",$url,$function); 291 | } 292 | 293 | static function delete($url, $function){ 294 | return self::match("DELETE",$url,$function); 295 | } 296 | 297 | static function option($url, $function){ 298 | return self::match("OPTION",$url,$function); 299 | } 300 | 301 | function name($name){ 302 | if( count(self::$latestMethods) ) { 303 | for($i = 0; $i < count(self::$latestMethods); $i++){ 304 | $method = self::$latestMethods[$i]; 305 | $lastID = count(self::$routes[$method]) - 1; 306 | 307 | self::$routes[$method][$lastID]["name"] = $name; 308 | if($i == 0) 309 | self::$names[$name] = [$method,$lastID]; 310 | } 311 | } 312 | return $this; 313 | } 314 | 315 | function where($name,$where=null){ 316 | for( $i = 0; $i < count(self::$latestMethods); $i++) { 317 | $method = self::$latestMethods[$i]; 318 | $lastID = count(self::$routes[$method]) - 1; 319 | if ($where === null && is_array($name)) 320 | self::$routes[$method][$lastID]["where"] = array_merge(self::$routes[$method][$lastID]["where"],$name); 321 | else 322 | self::$routes[$method][$lastID]["where"][$name] = $where; 323 | } 324 | return $this; 325 | } 326 | 327 | static function route($name,$parameters=null){ 328 | if(array_key_exists($name,self::$names)) { 329 | $url = self::$routes[ self::$names[$name][0] ][ self::$names[$name][1] ]["url"]; 330 | if(count($parameters)) { 331 | foreach ($parameters as $key => $value) { 332 | $url = preg_replace("@{" . $key . "}@", $value, $url); 333 | $url = preg_replace("@{" . $key . "\?}@", $value, $url); 334 | } 335 | } 336 | 337 | $url = preg_replace("@{/}@","/",$url); 338 | $url = preg_replace("@{([0-9a-zA-Z]+)\?}@","",$url); 339 | 340 | if(!preg_match_all("@{(.*?)}@",$url,$matches)) 341 | return $url; 342 | else{ 343 | $str = "Eksik Parametre : "; 344 | foreach ($matches[1] as $id=>$match) 345 | $str .= ($id != 0?', ':null).$match; 346 | return $str; 347 | } 348 | } 349 | } 350 | 351 | static function currentRoute(){ 352 | return self::$current; 353 | } 354 | 355 | static function currentRouteURL(){ 356 | if(is_array(self::$current)) 357 | return self::$current["url"]; 358 | return false; 359 | } 360 | 361 | static function currentRouteName(){ 362 | if(is_array(self::$current)) 363 | return self::$current["name"]; 364 | return false; 365 | } 366 | } -------------------------------------------------------------------------------- /System/Helpers/Session.php: -------------------------------------------------------------------------------- 1 | addFileExtension('.edge.php'); 14 | 15 | if($cache === false) 16 | $edge = new Edge($loader); 17 | else 18 | $edge = new Edge($loader, null, new EdgeFileCache( 'App/Cache')); 19 | return $edge->render($file, $vars); 20 | 21 | } 22 | } -------------------------------------------------------------------------------- /System/Plugins/Setting.php: -------------------------------------------------------------------------------- 1 | file = $file; 12 | $this->load($this->file); 13 | } 14 | 15 | function load($file){ 16 | $this->settings = App::loadFile($this->dir.$file); 17 | } 18 | 19 | function get($key=null){ 20 | if($key) 21 | return stripslashes($this->settings[$key]); 22 | else return $this->settings; 23 | } 24 | 25 | function set($key,$value){ 26 | $this->settings[$key] = $value; 27 | } 28 | 29 | function drop(){ 30 | $this->settings = []; 31 | } 32 | 33 | function truncate(){ 34 | foreach($this->settings as $key => $value) 35 | $this->settings[$key] = null; 36 | } 37 | 38 | function copy($arr = []){ 39 | foreach($arr as $key => $value) 40 | $this->settings[$key] = $value; 41 | } 42 | 43 | function save($arr = null){ 44 | if($arr) 45 | $this->copy($arr); 46 | 47 | $string = 'settings as $key => $value){ 51 | $string .= ' "' . $key . '"=>"' . $value . '", 52 | '; 53 | } 54 | $string .= ' ];'; 55 | App::writeFile($this->dir.$this->file,$string); 56 | } 57 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eylmz/wd-mvc", 3 | "type": "project", 4 | "description": "PHP WD MVC Framework", 5 | "keywords": [ 6 | "php", 7 | "wd", 8 | "mvc", 9 | "mini", 10 | "framework" 11 | ], 12 | "homepage": "https://github.com/eylmz058/PHP-MVC", 13 | "license": "MIT", 14 | "authors": [ 15 | { 16 | "name": "Emre YILMAZ", 17 | "email": "eylmz058@gmail.com", 18 | "homepage": "http://emre.pw", 19 | "role": "Developer" 20 | } 21 | ], 22 | "require": { 23 | "php": ">=5.4.0", 24 | "windwalker/edge": "~3.0", 25 | "catfan/Medoo": "^1.2" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "App\\": "App/", 30 | "System\\": "System/" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 |