IDeal

В предыдущих постах мы разработали минимальную структуру фреймворка. В этой статье, наведем немного лоска - добавим простенькую тему с bootstrap'ом, меню и подробнее рассмотрим работу шаблонизатора и роутера (маршрутизатора сайта). 

Роутер

В прошлой статье мы создали роутер, который используя логику регулярных выражений распознает входящую sef ссылку и направляет на нужный контроллер и его метод.

Т.е. из такой строки

/user/profile/12

роутер делает массив

array('controller'=>'user','action'=>'profile', 'id'=>15)

Мы не стали в прошлый раз писать пример использования такого решения. Исправим ситуацию, но перед этим доработаем роутер.

Перенесем массив правил роутера в конфигурационный файл фреймворка. Этот массив будут заполнять разработчики, которые будут писать сайты на нашем фреймворке. Поэтому он должен быть максимально доступен.

...
'router' => array( 
	'([a-z0-9+_\-]+)/([a-z0-9+_\-]+)/([0-9]+)' => '$controller/$action/$id',
	'([a-z0-9+_\-]+)/([a-z0-9+_\-]+)' => '$controller/$action',
	'([a-z0-9+_\-]+)(/)?' => '$controller',
),
...

Кроме того вы можете видеть, что мы изменили правую часть массива.

Рассказать друзьям

В прошлой статье мы разобрали структуру фреймворка, но не его реализацию. Для того чтобы фреймворк начал функционаровать, нам потребуется его доработать. Для начала подключим файл конфигурацию. Мы обозначили файл, как config.php, но никак его не использовали.

По опыту разработки сразу оговорюсь, удобно использовать два файла конфигурации: первый для общих настроек - название сайта, адрес домена, время жизни куков, и второй для настроек подключения к БД. Это в первую очередь качается разработки на фреймворке. Так как для такой системы важно быстро развернуть ее на локальном компьютере и зачем перенести на сервер. При таком переносе, один из конфигов будет общим, а второй будет заполнен лишь единожды для каждого сервера. Поэтому определим два файла config.php и config.db.php

Структура этих файлов должна быть как можно проще. Идеальный вариант - ini файлы. Но для них нужно писать отдельные парсеры и они доступны из вне. Поэтому не будем изобретать велосипед, а сделаем простой php ассоциативный массив с парами ключ-значение.

Рассказать друзьям

Получить реальный IP пользователя

function get_ip() {
    //Just get the headers if we can or else use the SERVER global
    if ( function_exists( 'apache_request_headers' ) ) {
        $headers = apache_request_headers();
    } else {
        $headers = $_SERVER;
    }
    //Get the forwarded IP if it exists
    if ( array_key_exists( 'X-Forwarded-For', $headers ) && filter_var( $headers['X-Forwarded-For'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
        $the_ip = $headers['X-Forwarded-For'];
    } elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $headers ) && filter_var($headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        $the_ip = $headers['HTTP_X_FORWARDED_FOR'];
    } else {
        $the_ip = filter_var( $_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 );
    }
    return $the_ip;
}

Отправить POST запрос на PHP

function postRequest($url, $post = 0){
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url ); // отправляем на
	curl_setopt($ch, CURLOPT_HEADER, 0); // пустые заголовки
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвратить то что вернул сервер
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // следовать за редиректами
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);// таймаут4
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt'); // сохранять куки в файл
	curl_setopt($ch, CURLOPT_COOKIEFILE,  dirname(__FILE__).'/cookie.txt');
	curl_setopt($ch, CURLOPT_POST, $post!==0 ); // использовать данные в post
	if($post)
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
	$data = curl_exec($ch);
	curl_close($ch);
	return $data;
}

Пользоваться так

 

$data = postRequest('https://www.google.com/recaptcha/api/siteverify', array('secret'=>'','response'=>'', 'remoteip'=>''));

Как найти, где находится функция php

$reflFunc = new ReflectionFunction('function_name');
print $reflFunc->getFileName() . ':' . $reflFunc->getStartLine();

Как найти, где находится класс в php

идентично верхнему коду, можно найти и местоположение любого не встроенного класса в php

$ref = new ReflectionClass('Application'); 
print $ref->getFileName() . ':' . $ref->getStartLine();

Как получить все методы у объекта или класса в php

print_r(get_class_methods($obj));

Как удалить папку с файлами или почистить папку с файлами

function cleanDirectory($dir, $remove = false) {
	if ($objs = glob($dir."/*")) {
		foreach($objs as $obj) {
			is_dir($obj) ? cleanDirectory($obj, true) : unlink($obj);
		}
	}
	if ($remove) {
		rmdir($dir);
	}
}

пользуемся так

Если нужно просто отчистить директорию то запускаем без второго параметра, если после очистки нужно еще и удалить ее то вторым параметром подаем true

cleanDirectory('/home/www/files/images'); // очистка
cleanDirectory('/home/www/files/images', true); // удаление

Как отдать на загрузку какой-либо файл на сервере с помощью php

универсальный загрузчик выглядит так

function download ($file) {
	if (!empty($file) and file_exists($file) and is_file($file)) {
		if (ob_get_level()) {
			ob_end_clean();
		}

		header('Content-Description: File Transfer');
		header('Content-Type: application/octet-stream');
		header('Content-Disposition: attachment; filename=' . basename($file));
		header('Content-Transfer-Encoding: binary');
		header('Expires: 0');
		header('Cache-Control: must-revalidate');
		header('Pragma: public');
		header('Content-Length: ' . filesize($file));
		
		if ($fd = fopen($file, 'rb')) {
			while (!feof($fd)) {
				print fread($fd, 1024);
			}
			fclose($fd);
		}
	} else {
		header('HTTP/1.0 404 Not Found');
		echo 'File not found';
	}
	exit();
}

Сгенерировать строку из случайных символов

Часто надо сгененрировать случайную строку для соли или еще для чего

function generateHash ($length = 8){
	$password = "";
	$possible = "2346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ";
	$maxlength = strlen($possible);
	if ($length > $maxlength) {
		$length = $maxlength;
	}
	$i = 0; 
	while ($i < $length) { 
		$char = substr($possible, mt_rand(0, $maxlength-1), 1);
		if (!strstr($password, $char)) { 
			$password .= $char;
			$i++;
		}
	}
	return $password;
}

 

универсальный загрузчик выглядит так

Узнать, пришел ли запрос через AJAX

Этот способ работает только с jQuery. Она при AJAX запросе добавляет заголовок HTTP_X_REQUESTED_WITH=XMLHttpRequest в запрос

Поэтому, можно написать на сервере функцию проверки

function isAjax(){
	return isset($_SERVER['HTTP_X_REQUESTED_WITH']) and $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
}

 

 

Рассказать друзьям

Поиск по цвету на сайтеПри создании интернет магазина, по продаже материалов или иной продукции, в котором, фотография товара, это один из основных признаков его выбора, и сайт больше напоминает галерею, рано или поздно возникает потребность в поиске изображений по цвету. Задача довольно распространенная. Если вы с ней не сталкивались то еще столкнетесь. В этой заметке, я опишу, как организовать поиск по цвету на сайте.

Рассказать друзьям

На страницах этого блога уже было описано применение технологии memcache для кеширования веб страниц целиком. действительно, это очень удобная технология позволяет делать это очень быстро и надежно, при этом нет необходимости держать огромную папку закешированного содержимого. Все лежит в оперативной памяти.

Конечно, если памяти доступной для этого расширения не достаточно, то тут ничего не сделаешь. Но для выделенных сервером, как было в моем случае, это не проблема.

В этой статье я расскажу, как закешировать sql запросы к базе данных. 

Рассказать друзьям

Подкатегории

Все о разработке на фреймворке Yii