- Представление о MVC имею. Раньше писал пару проектов на CodeIgniter, но на нём на мой взгляд мало что есть из коробки, и много времени уходит на разработку.С тех пор изобрели Composer, при должном желании прикручивается он и к CI в том числе :)
- Нужен современный не заброшенный фреймворк, с достаточным количеством документации. Не обязательно на русском, но будет плюсом.На русском - CodeIgniter, на не русском - Laravel, Symfony и другие.
- Хотелось бы большое количество подключаемого функционала из коробки, для экономии времени разработки. Например уже написанная логика авторизации, регистрации, восстановления пароля и разграничения по уровням доступа. Понимаю что всё равно придется немного допиливать под свои нужды, но времени это сэкономило бы кучу.Composer - решает 99% проблем, практически в любом фреймворке.
- Возможность работы с различными БД из коробкиПока фреймворков без этой штуки не видел, но есть... Вы не поверите, Composer, что бы сменить/поставить "другой" ORM, если Вам "текущий" чем-то не подошел.
- Поддержка кэширования из коробки. И желательно что бы была поддержка некешируемых областей при генерации страницы, а сам кэш был управляемым.То о чем Вы говорите, это: Varnish, Nginx+SSI и т.д. кэширование "из коробки" есть в Symfony (т.к. если его отключить, страницы может генерироваться феерически долго)
- Не тяжелый фреймворк, в котором оптимизирован код, и который не жрёт огромное количество ресурсов на сервере. Если будет поддержка PHP7 - тоже плюс.По моему, любой современный фреймворк, если уже даже "Битрикс" небеизвестный до этого до этого дошел... некоторые фреймворки вообще скоро будут требовать PHP7, а не только "поддерживать".
- Проект будет ориентировочно крутиться на nginx+php5-fpm. Думаю практически все фреймворки смогут работать в этой среде, но вдруг...Я пока таких "вдруг" не встречал. Если у админа голова и руки на месте - то никаких "вдруг" быть не должно. А вообще, у PHP версии 5.х, есть как минимум 3 основных "ветки", это <5.3, >=5.3 или 5.4+ и т.д., ещё кое-какие отличия были в 5.5 и 5.6, но не такие "разительные", подробности можно почитать в истории версий PHP. По этому, нужно конкретнее указывать версию, например, Laravel требует 5.6+
- Возможность масштабирования. В принципе не обязательно, но возможно однажды будет масштабироваться проект.Это не возможность фреймворка - а навык программиста/админа.
- Всякие плюшки из коробки типа каптчи, обработки и обрезки изображений и прочие приятности будут огромным плюсом и будут иметь «больший вес» при выборе, т.к. важна простота и скорость разработки.
Большое спасибо за время уделенное прочтению моего вопроса, и огромное спасибо за Ваши ответы.Не за что! Кнопка "Мне нравиться" - сразу под сообщением :D
лижь бы
Когда я программирую я вижу насколько ужасен мой код, но поняттия не имею как сделать его лучше
Или крсота прийдет с опытом
можно прогуглить но это минус к времени
деайны переработки так как новчек
GET, POST, PUT и другие
] и компоненты URI.например: https://ru.wikipedia.org/wiki/URI?foo=bar#title
[схема: https] :// [источник: ru.wikipedia.org] [путь: /wiki/URI] [запрос: ?foo=bar] [фрагмент: #title]
// файл index.php
// Маршруты
// [маршрут => функция которая будет вызвана]
$routes = [
// срабатывает при вызове корня или /index.php
'/' => 'hello',
// срабатывает при вызове /about или /index.php/about
'/about' => 'about',
// динамические страницы
'/page' => 'page'
];
// возвращает путь запроса
// вырезает index.php из пути
function getRequestPath() {
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
return '/' . ltrim(str_replace('index.php', '', $path), '/');
}
// наш роутер, в который передаются маршруты и запрашиваемый путь
// возвращает функцию если маршшрут совпал с путем
// иначе возвращает функцию notFound
function getMethod(array $routes, $path) {
// перебор всех маршрутов
foreach ($routes as $route => $method) {
// если маршрут сопадает с путем, возвращаем функцию
if ($path === $route) {
return $method;
}
}
return 'notFound';
}
// функция для корня
function hello() {
return 'Hello, world!';
}
// функция для страницы "/about"
function about() {
return 'About us.';
}
// чуть более сложный пример
// функция отобразит страницу только если
// в запросе приходит id и этот id равен
// 33 или 54
// [/page?id=33]
function page() {
$pages = [
33 => 'Сага о хомячках',
54 => 'Мыши в тумане'
];
if (isset($_GET['id']) && isset($pages[$_GET['id']])) {
return $pages[$_GET['id']];
}
return notFound();
}
// метод, который отдает заголовок и содержание для маршрутов,
// которые не существуют
function notFound() {
header("HTTP/1.0 404 Not Found");
return 'Нет такой страницы';
}
// Роутер
// получаем путь запроса
$path = getRequestPath();
// получаем функцию обработчик
$method = getMethod($routes, $path);
// отдаем данные клиенту
echo $method();
index.php
about.php
contact.php
...
function get_unique_array(array1, array2) {
return array1.filter(function(val) {
return array2.indexOf(val) != -1;
});
}
var
arr_1 = ['a', 'b', 'c'],
arr_2 = ['b', 'c', 'd', 'e'];
console.log(get_unique_array(arr_1, arr_2)); // ["b", "c"]
...подавляющее число действительно серьезных коммерческих проектов, как правило связанных с производством ништяков, реализуются коллективом, а не психами-одиночками, и никакая координация через e-mail, web-камеры и мессенджеры не спасет проект от бесславной гибели, если сотрудники не будут IRL бегать от стола к столу, тыкать друг-друга в мониторы и посещать всяческие стафф-митинги.
<?php
/**
* Простой роутер
* @devg
*/
final class RouterLite {
public static $routes = array();
private static $params = array();
public static $requestedUrl = '';
/**
* Добавить маршрут
*/
public static function addRoute($route, $destination=null) {
if ($destination != null && !is_array($route)) {
$route = array($route => $destination);
}
self::$routes = array_merge(self::$routes, $route);
}
/**
* Разделить переданный URL на компоненты
*/
public static function splitUrl($url) {
return preg_split('/\//', $url, -1, PREG_SPLIT_NO_EMPTY);
}
/**
* Текущий обработанный URL
*/
public static function getCurrentUrl() {
return (self::$requestedUrl?:'/');
}
/**
* Обработка переданного URL
*/
public static function dispatch($requestedUrl = null) {
// Если URL не передан, берем его из REQUEST_URI
if ($requestedUrl === null) {
$uri = reset(explode('?', $_SERVER["REQUEST_URI"]));
$requestedUrl = urldecode(rtrim($uri, '/'));
}
self::$requestedUrl = $requestedUrl;
// если URL и маршрут полностью совпадают
if (isset(self::$routes[$requestedUrl])) {
self::$params = self::splitUrl(self::$routes[$requestedUrl]);
return self::executeAction();
}
foreach (self::$routes as $route => $uri) {
// Заменяем wildcards на рег. выражения
if (strpos($route, ':') !== false) {
$route = str_replace(':any', '(.+)', str_replace(':num', '([0-9]+)', $route));
}
if (preg_match('#^'.$route.'$#', $requestedUrl)) {
if (strpos($uri, '$') !== false && strpos($route, '(') !== false) {
$uri = preg_replace('#^'.$route.'$#', $uri, $requestedUrl);
}
self::$params = self::splitUrl($uri);
break; // URL обработан!
}
}
return self::executeAction();
}
/**
* Запуск соответствующего действия/экшена/метода контроллера
*/
public static function executeAction() {
$controller = isset(self::$params[0]) ? self::$params[0]: 'DefaultController';
$action = isset(self::$params[1]) ? self::$params[1]: 'default_method';
$params = array_slice(self::$params, 2);
return call_user_func_array(array($controller, $action), $params);
}
}
?>
<?php
// маршруты (можно хранить в конфиге приложения)
// можно использовать wildcards (подстановки):
// :any - любое цифробуквенное сочетание
// :num - только цифры
// в результирующее выражение записываются как $1, $2 и т.д. по порядку
$routes = array(
// 'url' => 'контроллер/действие/параметр1/параметр2/параметр3'
'/' => 'MainController/index', // главная страница
'/contacts' => 'MainController/contacts', // страница контактов
'/blog' => 'BlogController/index', // список постов блога
'/blog/:num' => 'BlogController/viewPost/$1' // просмотр отдельного поста, например, /blog/123
'/blog/:any/:num' => 'BlogController/$1/$2' // действия над постом, например, /blog/edit/123 или /blog/dеlete/123
'/:any' => 'MainController/anyAction' // все остальные запросы обрабатываются здесь
));
// добавляем все маршруты за раз
RouterLite::addRoute($routes);
// а можно добавлять по одному
RouterLite::addRoute('/about', 'MainController/about');
// непосредственно запуск обработки
RouterLite::dispatch();
?>