first commit
Этот коммит содержится в:
87
src/App.php
Обычный файл
87
src/App.php
Обычный файл
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
use MyApp\Core\Config;
|
||||
use MyApp\Core\Router;
|
||||
|
||||
class App
|
||||
{
|
||||
private $prefix = 'MyApp\\';
|
||||
|
||||
private $classDirs = [
|
||||
'Controller\\' => 'controllers/',
|
||||
'Core\\' => 'core/',
|
||||
'Model\\' => 'models/',
|
||||
'View\\' => 'views/',
|
||||
];
|
||||
private $basedir = __DIR__;
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
public $config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
global $app;
|
||||
$app = $this;
|
||||
spl_autoload_register([$this, 'autoload']);
|
||||
|
||||
$this->config = (new Config())->setDbName('db')
|
||||
->setDbPort(3306)
|
||||
->setDbUser('user')
|
||||
->setDbPassword('password')
|
||||
->setSrcDir($this->basedir)
|
||||
->setTimezone('Europe/Moscow')
|
||||
->setClassDirs($this->classDirs)
|
||||
->setControllersDir($this->basedir.'/controllers/')
|
||||
->setControllersNamespace('\\MyApp\\Controller\\')
|
||||
->setSiteName('BadPing. Nagios better');
|
||||
|
||||
new Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload function.
|
||||
*
|
||||
* @param string $className
|
||||
*/
|
||||
public function autoload(string $className)
|
||||
{
|
||||
if (0 !== strpos($className, $this->prefix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fileName = substr($className, strlen($this->prefix));
|
||||
$fileName = str_replace(array_keys($this->classDirs), array_values($this->classDirs), $fileName);
|
||||
$fileName = $this->basedir.'/'.str_replace('\\', '/', $fileName).'.php';
|
||||
|
||||
if (file_exists($fileName)) {
|
||||
require $fileName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse tags from method comments.
|
||||
*
|
||||
* @param string $comment
|
||||
* @param string $tags
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function parseTagsFromComment(string $comment, string $tags = 'RouteRegExp|HttpMethod')
|
||||
{
|
||||
if (preg_match_all("/^\\ *\\* \\@(?<type>$tags)\\ =\\ \"(?<value>.*)\\\".*\$/m", $comment, $matches)) {
|
||||
$out = [];
|
||||
foreach ($matches['type'] as $key => $type) {
|
||||
if ('HttpMethod' == $type) {
|
||||
$out[$type] = explode(',', $matches['value'][$key]);
|
||||
} else {
|
||||
$out[$type] = $matches['value'][$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
17
src/controllers/DefaultController.php
Обычный файл
17
src/controllers/DefaultController.php
Обычный файл
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Controller;
|
||||
|
||||
use MyApp\Core\Controller;
|
||||
use MyApp\View\DefaultView as View;
|
||||
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
/**
|
||||
* @RouteRegExp = "|^/$|"
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
(new View())->index();
|
||||
}
|
||||
}
|
19
src/controllers/ErrorsController.php
Обычный файл
19
src/controllers/ErrorsController.php
Обычный файл
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Controller;
|
||||
|
||||
use MyApp\Core\Controller;
|
||||
|
||||
class ErrorsController extends Controller
|
||||
{
|
||||
public function get404()
|
||||
{
|
||||
http_response_code(404);
|
||||
echo 404;
|
||||
}
|
||||
|
||||
public function post404()
|
||||
{
|
||||
echo 404;
|
||||
}
|
||||
}
|
235
src/core/Config.php
Обычный файл
235
src/core/Config.php
Обычный файл
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Core;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dbName;
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $dbPort;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dbUser;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dbPassword;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $classDirs;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $srcDir;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $controllersDir;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $controllersNamespace;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $siteName;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDbName(): string
|
||||
{
|
||||
return $this->dbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dbName
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setDbName(string $dbName)
|
||||
{
|
||||
$this->dbName = $dbName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getDbPort(): int
|
||||
{
|
||||
return $this->dbPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $dbPort
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setDbPort(int $dbPort)
|
||||
{
|
||||
$this->dbPort = $dbPort;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDbUser(): string
|
||||
{
|
||||
return $this->dbUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dbUser
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setDbUser(string $dbUser)
|
||||
{
|
||||
$this->dbUser = $dbUser;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDbPassword(): string
|
||||
{
|
||||
return $this->dbPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dbPassword
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setDbPassword(string $dbPassword)
|
||||
{
|
||||
$this->dbPassword = $dbPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $timezone
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimezone(string $timezone)
|
||||
{
|
||||
date_default_timezone_set($timezone);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getClassDirs(): array
|
||||
{
|
||||
return $this->classDirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classDirs
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setClassDirs(array $classDirs)
|
||||
{
|
||||
$this->classDirs = $classDirs;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSrcDir(): string
|
||||
{
|
||||
return $this->srcDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $srcDir
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setSrcDir(string $srcDir)
|
||||
{
|
||||
$this->srcDir = $srcDir;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControllersDir(): string
|
||||
{
|
||||
return $this->controllersDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllersDir
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setControllersDir(string $controllersDir)
|
||||
{
|
||||
$this->controllersDir = $controllersDir;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControllersNamespace(): string
|
||||
{
|
||||
return $this->controllersNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $controllersNamespace
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setControllersNamespace(string $controllersNamespace)
|
||||
{
|
||||
$this->controllersNamespace = $controllersNamespace;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSiteName(): string
|
||||
{
|
||||
return $this->siteName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $siteName
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public function setSiteName(string $siteName)
|
||||
{
|
||||
$this->siteName = $siteName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
7
src/core/Controller.php
Обычный файл
7
src/core/Controller.php
Обычный файл
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Core;
|
||||
|
||||
class Controller
|
||||
{
|
||||
}
|
7
src/core/Model.php
Обычный файл
7
src/core/Model.php
Обычный файл
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Core;
|
||||
|
||||
class Model
|
||||
{
|
||||
}
|
103
src/core/Router.php
Обычный файл
103
src/core/Router.php
Обычный файл
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Core;
|
||||
|
||||
use ReflectionMethod;
|
||||
|
||||
/**
|
||||
* Class Router.
|
||||
*/
|
||||
class Router
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $routes = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->getRoutesFromControllers();
|
||||
$this->addRoute('/^.*$/', 'MyApp\\Controller\\ErrorsController', 'get404', ['GET']);
|
||||
$this->addRoute('/^.*$/', 'MyApp\\Controller\\ErrorsController', 'post404', ['POST', 'PUT', 'DELETE']);
|
||||
|
||||
$this->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Routes from a comment on method in Controllers.
|
||||
*/
|
||||
private function getRoutesFromControllers()
|
||||
{
|
||||
/* @var \App $app */
|
||||
global $app;
|
||||
|
||||
/* @var Config $config */
|
||||
$config = $app->config;
|
||||
|
||||
$controllersDir = $config->getControllersDir();
|
||||
$controllersNamespace = $config->getControllersNamespace();
|
||||
|
||||
$files = scandir($controllersDir);
|
||||
foreach ($files as $file) {
|
||||
$className = strstr($file, '.php', true);
|
||||
$fileName = $controllersDir.$file;
|
||||
if (is_file($fileName) && false !== $className) {
|
||||
try {
|
||||
$refClass = new \ReflectionClass($controllersNamespace.$className);
|
||||
$methods = $refClass->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||
foreach ($methods as $method) {
|
||||
$tags = $app->parseTagsFromComment($method->getDocComment());
|
||||
if (is_array($tags)) {
|
||||
if (array_key_exists('RouteRegExp', $tags)) {
|
||||
if (!array_key_exists('HttpMethod', $tags)) {
|
||||
$tags['HttpMethod'] = ['GET'];
|
||||
}
|
||||
|
||||
$this->addRoute($tags['RouteRegExp'], $method->class, $method->name, $tags['HttpMethod']);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
var_dump($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add route to array.
|
||||
*
|
||||
* @param string $regExp
|
||||
* @param string $className
|
||||
* @param string $classMethod
|
||||
* @param array $httpMethods
|
||||
*/
|
||||
private function addRoute(string $regExp, string $className, string $classMethod, array $httpMethods)
|
||||
{
|
||||
foreach ($httpMethods as $httpMethod) {
|
||||
$this->routes[strtoupper($httpMethod)][] = [$regExp, $className, $classMethod];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run parse request.
|
||||
*/
|
||||
private function run()
|
||||
{
|
||||
if (array_key_exists($_SERVER['REQUEST_METHOD'], $this->routes)) {
|
||||
foreach ($this->routes[$_SERVER['REQUEST_METHOD']] as $route_array) {
|
||||
if (preg_match($route_array[0], $_SERVER['REQUEST_URI'], $matches)) {
|
||||
$obj = new $route_array[1]();
|
||||
$param_arr = [];
|
||||
foreach ($matches as $key => $value) {
|
||||
if (!is_int($key)) {
|
||||
$param_arr[] = $value;
|
||||
}
|
||||
}
|
||||
call_user_func_array([$obj, $route_array[2]], $param_arr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
src/core/View.php
Обычный файл
44
src/core/View.php
Обычный файл
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\Core;
|
||||
|
||||
class View
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
public function json($data)
|
||||
{
|
||||
}
|
||||
|
||||
public function render($template)
|
||||
{
|
||||
/* @var \App $app */
|
||||
global $app;
|
||||
|
||||
$fileName = $app->config->getSrcDir().'/templates/'.$template.'.tpl.php';
|
||||
|
||||
if (file_exists($fileName)) {
|
||||
ob_start();
|
||||
require $fileName;
|
||||
ob_end_flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*
|
||||
* @return View
|
||||
*/
|
||||
public function setTitle(string $title)
|
||||
{
|
||||
/* @var \App $app */
|
||||
global $app;
|
||||
|
||||
$this->title = $title.' — '.$app->config->getSiteName();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
3
src/templates/default/index.tpl.php
Обычный файл
3
src/templates/default/index.tpl.php
Обычный файл
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
require __DIR__.'/../shared/head.php';
|
18
src/templates/shared/head.php
Обычный файл
18
src/templates/shared/head.php
Обычный файл
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="ru-RU">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicon/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicon/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="mask-icon" href="/assets/img/favicon/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="stylesheet" href="/assets/css/normalize.css">
|
||||
<link rel="stylesheet" href="/assets/css/style.css">
|
||||
<title><?= $this->title; ?></title>
|
||||
</head>
|
13
src/views/DefaultView.php
Обычный файл
13
src/views/DefaultView.php
Обычный файл
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace MyApp\View;
|
||||
|
||||
use MyApp\Core\View;
|
||||
|
||||
class DefaultView extends View
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$this->setTitle('Index')->render('default/index');
|
||||
}
|
||||
}
|
Ссылка в новой задаче
Block a user