Masonry — вывод блоков разных размеров в виде кирпичной кладки для html страниц и WordPress

Сегодня хочу затронуть один очень интересный материал, который будет полезен для тех кто начал заниматься версткой и созданием своих сайтов. Речь пойдет об эффекте Masonry — вывод блоков разных размеров в виде кирпичной кладки. В статье покажу как это сделать для html страниц и сайтов на WordPress. Отличаться мало чем будет, но все же свои моменты есть. Так что, если вы захотите на своем сайте внедрить подобный эффект, эта статья вам поможет в этом.

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

Чтобы сделать такое на своем сайте, нужно выполнить несколько шагов. Давайте приступим к воплощению задуманного

Скрипт Masonry
В самом начале стоит понять, что вся сетка создается благодаря скрипту Masonry. Поэтому для работы нужен он, но так как он работает на основе jQuery, нужно подключить библиотеку. Подключать нужно такую строку:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

Если вы используете WordPress, то делать этого не нужно. У WordPress библиотека подключена по умолчанию, разве что вы специально ее отключали.


После библиотеки нужно уже подключать скрипт Masonry. Сначала рассмотрим пример для HTML страниц, для WordPress рассмотрим ниже. Скрипт можно взять из архива, что можно скачать по ссылке в начале статьи. В таком случаи он будет запускаться с вашего сайта. Подключается примерно так:

<script src="masonry.js"></script>

Нужно только указать правильный путь к файлу masonry.js. Если у вас все файлы в корне то так и оставить, а если в папках то весь путь вложенности. Используйте статью с инструкцией подключения.

Так же можно просто указать в подключении ссылку к стороннему ресурсу, например так:

<script src="https://masonry.desandro.com/masonry.pkgd.min.js"></script>

Таким образом скрипт будет подключаться с чужого ресурса, который предоставляет такую возможность.

Не указывайте ссылки с моего сайта или сайтов других вебсамстеров. Так вы создаете нагрузку на чужой сайт и со временем ваше подключение будет заблокировано.


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

Это будет wp_enqueue_script. Найдите функцию что подключает другие скрипты и рядом с ними добавьте подключение Masonry, которое уже вшито в WordPress и его нужно только подключить.

Перед изменением function.php, обязательно сохраните его копию, чтобы в дальнейшем, в случаи ошибки, вернуть все как было.


wp_enqueue_script('masonry');

Если не можете найти подключение скриптов, то просто добавляете в самый конец function.php перед закрывающим тегом PHP ?>. Если его нет, то просто в самый конец. Добавляйте вот такую функцию:

function masonry_scr(){
wp_enqueue_script('masonry');
}
add_action( 'wp_enqueue_scripts', 'masonry_scr' );

После подключения скрипта Masonry, чтобы он начал работать его нужно применить к нашему контейнеру. Запуск скрипта нужно сделать после библиотеки jQuery и самого скрипта Masonry. Выглядит он так:

<script>
jQuery(document).ready(function($){
var $container = $('#container');$container.masonry({columnWidth:'.item',itemSelector: '.item'});
});
</script>

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

$('#container') - тут мы указываем ID нашего контейнера, внутри которого будут блоки которые нужно выровнять в сетке.
columnWidth:'.item' - параметр, который задает ширину блоков. В нашем случаи мы указали ширину равную стилям блока с классом item, поэтому ширину зададим в CSS стилях.
itemSelector: '.item' - указываем скрипту блоки с каким классом будут использованы при построении сетки.
У Masonry есть еще некоторые параметры, которые используются редко, если вы хотите детально изучить, можете поискать информацию ее очень много по Masonry. Для данного примера хватит и этих двух.

Таким образом вы активируете Masonry на вашем сайте и теперь можно уже перейти к следующим шагам.

HTML разметка
Сначала рассмотрим вариант для HTML страниц и тут все просто, вам нужно просто добавить примерно такую разметку:

<div id="container">
<div class="item">
<a class="item_link" href="/"><img src="images.jpg" >
<h2>Lorem Ipsum - текст рыба</h2>
<p>Что такое Lorem Ipsum? Lorem Ipsum - это текст-"рыба", часто используемый в печати и вэб-дизайне. Lorem Ipsum является стандартной "рыбой"…</p>
</a>
</div>
<div class="item w2">
<a class="item_link" href="/"><img src="images2.jpg" >
<h2>Lorem Ipsum - текст рыба</h2>
<p>Что такое Lorem Ipsum? Lorem Ipsum - это текст-"рыба", часто используемый в печати и вэб-дизайне. Lorem Ipsum является стандартной "рыбой"…</p>
</a>
</div>

//дальше любое количество блоков

</div>

Как видите наш код обернут в родительский контейнер с ID - container. Внутри те самые блоки с классом item из которых будет построена сетка. Блоков может быть любое количество. В нашем примере, четным блокам помимо item еще присвоен класс w2. Это не Masonry, это моя доработка, для того чтобы задавать для четных блоков уникальные стили. Если вам это не нужно, то можно не добавлять второй класс.

Теперь рассмотрим вариант для WordPress. Тут немого сложнее, но если вы работаете с этой системой, то должны разбираться в циклах и как они устроены. Именно к циклу мы и применим Masonry. Выглядеть это будет примерно так:

<div id="container">
<?php  if (have_posts()): $one = true; while (have_posts()) : the_post(); ?>
<div class="item <?php if(!$one == true) echo "w2" ?>" >
<a class="item_link" href="<?php the_permalink() ?>"><?php the_post_thumbnail(); ?>
<h2><?php the_title(); ?></h2>
<?php echo wp_trim_words( get_the_content(), 20); ?>
</a>
</div>
<?php
$one = !$one; 
endwhile; 
the_posts_pagination($args = array('show_all' => false,'end_size' => 2,'mid_size' => 2,'prev_next' => true,'prev_text' => 'Назад','next_text'  => 'Вперед','add_args' => false,'add_fragment' => '','before_page_number' => '','after_page_number' => '','screen_reader_text' => ' ',));  else : echo '404 страница не найдена!'; endif; ?>
</div>

Как и с версией для HTML, оборачиваем цикл в контейнер с ID - container. Внутри цикла будут генерироваться те же блоки с классом item и с классом w2 четные. WordPress генерирует одинаковые блоки согласно указанным параметрам. Если у вас будут разно размерные миниатюры, разной длины заглавия для записей и разная длина текста, то отличимые стили для четных блоков вам не надо, в противном случаи блоки будут почти одинаковы и сетка не будет выглядеть интересно. Если не хотите четным блокам добавлять другие стили, то код будет таким:

<div id="container">
<?php  if (have_posts()): while (have_posts()) : the_post(); ?>
<div class="item" >
<a class="item_link" href="<?php the_permalink() ?>"><?php the_post_thumbnail(); ?>
<h2><?php the_title(); ?></h2>
<?php echo wp_trim_words( get_the_content(), 20); ?>
</a>
</div>
<?php
endwhile; 
the_posts_pagination($args = array('show_all' => false,'end_size' => 2,'mid_size' => 2,'prev_next' => true,'prev_text' => 'Назад','next_text'  => 'Вперед','add_args' => false,'add_fragment' => '','before_page_number' => '','after_page_number' => '','screen_reader_text' => ' ',));  else : echo '404 страница не найдена!'; endif; ?>
</div>

Данные циклы включают в себя и постраничную пагинацию. Поэтому количество выводимых блоков в сетке укажите в общих настройках чтения в консоли администратора. Данный цикл можно добавлять в файлы:

content.php
index.php
category.php
archive.php
И другие файлы, в зависимости от вашей темы. Внутрь цикла можете добавлять любые элементы, главное внутрь блока item. Это могут быть миниатюры, кнопки, тексты, заголовки и тд. Все зависит от вашей фантазии. Что касается разметки на этом все, остались лишь стили.

CSS стили
Стили для простых страниц и WordPress одинаковы, так что добавьте следующие стили в свой файл стилей:

#container{max-width:1200px;margin:15px auto 0;position:relative;min-height:100vh;}
.item{width:23%;margin:1%;overflow:hidden;text-align:center;box-shadow: 0px 10px 35px 0px rgba(0, 0, 0, 0.1);-webkit-box-shadow: 0px 10px 35px 0px rgba(0, 0, 0, 0.1);border-radius:15px;-webkit-border-radius:15px;}
.item,.item > *{box-sizing:content-box;-webkit-box-sizing:content-box;}
.item img {height:250px;width:100%;-webkit-border-radius:0;border-radius:0;}
.w2 img{height:350px;}
.item h2{font-weight:bold;font-size:20px;line-height:25px;padding:5px;}
.item p{font-size:15px;line-height:19px;padding:5px;}
.item a{height:100%;display:block;position:relative;overflow:hidden;color:#212121;text-decoration:none;}
.item a:hover{position:relative;z-index:2;color:#f00;}

@media (max-width:900px){
.item {width:45%;margin:2%;}
}

@media (max-width:550px){
.item {width:95%;margin:2%;}
}

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

Если все сделаете правильно, то результат не заставит себя ждать.

Добавлено: 13 Марта 2022 13:04:37 Добавил: Андрей Ковальчук

Подгрузка контента при прокрутке (бесконечная лента)

Пример реализации «Бесконечной ленты» с применением PHP, БД MySQL, и JQuery Ajax.

Формирование списка
Первый PHP-скрипт выводит только первые 12 записей из таблицы `prods` (записей может быть и больше, главное чтобы высота блока была больше высоты окна браузера).

Ниже, списка товаров выводится
<div id="showmore-triger">, который выполняет роль индикатора загрузки с гифкой ajax-loader.gif и того что пользователь уже доскроллил до этого элемента.

<?php
// Кол-во элементов
$limit = 12; 
 
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');
 
// Получение записей для первой страницы
$sth = $dbh->prepare("SELECT * FROM `prods` LIMIT {$limit}");
$sth->execute();	
$items = $sth->fetchAll(PDO::FETCH_ASSOC);	
 
// Кол-во страниц 
$sth = $dbh->prepare("SELECT COUNT(`id`) FROM `prods`");
$sth->execute();
$total = $sth->fetch(PDO::FETCH_COLUMN);
$amt = ceil($total / $limit);
?>
	
<div id="showmore-list">
	<div class="prod-list">
		<?php foreach ($items as $row): ?>
		<div class="prod-item">
			<div class="prod-item-img">
				<img src="/images/<?php echo $row['img']; ?>" alt="">	
			</div>
			<div class="prod-item-name">
				<?php echo $row['name']; ?>		
			</div>
		</div>
		<?php endforeach; ?>
	</div>
</div>
 
<div id="showmore-triger" data-page="1" data-max="<?php echo $amt; ?>">
	<img src="ajax-loader.gif" alt="">
</div>


CSS-стили:
#showmore-triger {
	text-align: center;
	padding: 10px;
	background: #ffdfdf;
}
 
/* Вывод товаров */
.prod-list {
	overflow: hidden;
	margin: 0 0 20px 0;
}
.prod-item {
	width: 174px;
	height: 230px;
	float: left;
	border: 1px solid #ddd;
	padding: 20px;
	margin: 0 20px 20px 0;
	text-align: center;
	border-radius: 6px;
}
.prod-item-img {
	width: 100%;
}
.prod-item-name {
	font-size: 13px;
	line-height: 16px;
}
 
.prod-list .prod-item:nth-child(3n) {
	margin-right: 0
}


JS-скрипт подгрузки контента
В нём отслеживается скроллинг страницы и в нужный момент отправляется AJAX-запрос на /ajax.php?page=x с номером следующей страницы, который возвращает следующую страницу записей, далее они вставляются в общий список.

При выводе всех страниц из БД, элемент с id="showmore-triger" удаляется методом JQuery remove() – он удаляет элемент из дерева DOM, а также все его JS-события.

<script src="/jquery/2.1.1/jquery.min.js"></script>
 
<script>
var block_show = false;
 
function scrollMore(){
	var $target = $('#showmore-triger');
	
	if (block_show) {
		return false;
	}
 
	var wt = $(window).scrollTop();
	var wh = $(window).height();
	var et = $target.offset().top;
	var eh = $target.outerHeight();
	var dh = $(document).height();   
 
	if (wt + wh >= et || wh + wt == dh || eh + et < wh){
		var page = $target.attr('data-page');	
		page++;
		block_show = true;
 
		$.ajax({ 
			url: '/ajax.php?page=' + page,  
			dataType: 'html',
			success: function(data){
				$('#showmore-list .prod-list').append(data);
				block_show = false;
			}
		});
 
		$target.attr('data-page', page);
		if (page ==  $target.attr('data-max')) {
			$target.remove();
		}
	}
}
 
$(window).scroll(function(){
	scrollMore();
});
	
$(document).ready(function(){ 
	scrollMore();
});
</script>

Код файла ajax.php
Скрип получает обрабатывает переменную $_GET['page'] и нужны записи из БД.

<?php
// Кол-во элементов
$limit = 12; 
 
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');
 
// Получение записей для текущей страницы
$page = intval(@$_GET['page']);
$page = (empty($page)) ? 1 : $page;				
$start = ($page != 1) ? $page * $limit - $limit : 0;
$sth = $dbh->prepare("SELECT * FROM `prods` LIMIT {$start}, {$limit}");
$sth->execute();	
$items = $sth->fetchAll(PDO::FETCH_ASSOC);				
 
foreach ($items as $row) {
	?>
	<div class="prod-item">
		<div class="prod-item-img">
			<img src="/images/<?php echo $row['img']; ?>" alt="">	
		</div>
		<div class="prod-item-name">
			<?php echo $row['name']; ?>		
		</div>
	</div>
	<?php
}

Добавлено: 10 Января 2022 07:34:19 Добавил: Андрей Ковальчук

Разница дат в MySQL в минутах

Как сравнить две временные метки с форматом yyyy-mm-dd hh-mm-ss , чтобы получить общую разницу в минутах? Метки времени извлекаются из MySQL. До сих пор я пытался использовать time_t или даже разбить всю строку для сравнения, но проблема с последним заключается в том, что он не распознает разницу...


Разница во времени в минутах:

SELECT ROUND(TIME_TO_SEC(timediff(date1,date2))/60) AS diff

Пример:

SELECT ROUND(TIME_TO_SEC(timediff('2014-01-01 11:29:00','2014-01-01 07:27:21'))/60) AS diff

Результат:

242


Разница во времени в часах:

SELECT ROUND(TIME_TO_SEC(timediff(date1,date2))/60/60) AS diff

если вам нужно количество часов с дробями, удалите ROUND.

Добавлено: 13 Декабря 2021 05:38:44 Добавил: Андрей Ковальчук

Как создать Windows Forms проект на C++

C++

Windows Forms — интерфейс программирования приложений, отвечающий за графический интерфейс пользователя. Он является частью .Net Framework и создан для того, чтобы упростить взаимодействие пользователя с элементами Win API. Причём не просто упростить, а буквально полностью скрыть низкоуровневое взаимодействие с графическими элементами путём создания набора базовых компонентов и классов. При этом используемые классы не привязаны к языку разработки, благодаря чему данный проект может использоваться как на родном для Microsoft C#, так и на других языках, например, C++, VB Net и F#. Но не смотря на свою кроссплатформенность в мире языков программирования, Windows Forms проекты легко создаются на C#, однако при попытке создания проекта на C++ возникает множество проблем.

Шаг 0. А вдруг получится сразу?
В настоящее время IDE, поддерживающих Windows forms, не так много — буквально одна только Visual Studio, более известная как просто "студия". Поэтому будем рассматривать создание и решение проблем именно в этой среде разработки. Первым шагом запустим студию, начнём создавать новый проект и попытаемся найти Windows forms проект для C++:

1.Создаём новый проект в студии
2.Ищем Winfows Forms для C++

Если у вас более старая версия Visual Studio, то интерфейс будет выглядеть немного иначе, однако данная функциональность будет той же. Также не исключено, что у Вас может быть данный тип проекта для C++ (на некоторых версиях формы для C++ были доступны сразу после установки IDE). Если же у Вас, как и у нас поиск не дал нужных результатов, то переходим к следующему шагу.

Шаг 1. Создание CLR проекта
Поскольку непосредственно Windows Forms проекта у нас не оказалось, мы обхитрим студию и создадим пустой CLR проект на С++. Для этого в том же окне поиска необходимо найти и выбрать Новый CLR проект, ввести имя (если нужно, то поменять директорию расположения проекта) и немного подождать, пока студия сделает свою работу.

1.Ищем пустой CLR проект (.Net Framework)
2.Создаём новый пустой CLR проект

В результате Visual Stido создаст новый C++ CLR проект.

Шаг 2. Добавить форму
Чтобы сделать CLR проект проектом Windows Forms, нужно просто добавить в него форму. Для этого в верхнем меню нужно выбрать Проект - Добавить новый элемент и в появившемся окне выбрать категорию Visual C++ - UI и затем выбрать Форма Windows Forms.

1.Проект -> Добавить новый элемент
2.Visual C++ -> UI -> Форма Windows Forms

После данной операции нас ждёт разочарование в виде ошибки Исключение из HRESULT: 0x8000000A:

Вместо формы получили ошибку

Шаг 3. Исправляем появившуюся ошибку
Данная ошибка появляется из-за того, что для создания окна формы приложению необходима основная программа, создающая форму и переключающая управление на неё, однако после добавления новой формы файл Form1.cpp предсказуемо создаётся пустым. Поэтому необходимо добавить основную программу в файл с формой:

#include "Form1.h"

#include <Windows.h>

using namespace имя_вашего_проекта;

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Application::Run(gcnew Form1);
    return 0;
}

В результате код файла Form1.cpp будет выглядеть следующим образом:

Добавление основной программы к форме

Шаг 4. Переоткрыть проект
Всё, что теперь осталось сделать — это закрыть текущее решение, а затем открыть его снова. Для этого можно закрыть саму студию, а можно выбрать в верхнем меню Файл - Закрыть решение, после чего в появившемся окне выбрать только что созданный проект и открыть его заново.

Форма создалась, можно добавлять компоненты

Благодаря добавленному коду основной программы, студия сможет создать форму и на экране появится изображение формы, на которую можно будет добавлять компоненты, задавать их свойства, а также свойства самой формы.

Добавлено: 28 Ноября 2021 07:37:46 Добавил: Андрей Ковальчук

Фильтрация и проверка данных PHP. Частые ошибки

Материал предназначен в основном для начинающих веб-программистов.

Введение.
Часто ко мне обращаются клиенты, у которых установлены самописные CMS или модули, написанные начинающими веб-программистами, которые не понимают, что нужно для защиты данных и зачастую копируют функции фильтрации, не задумываясь о том как они работают и что именно нужно с ними делать.

Здесь я постараюсь описать как можно подробнее частые ошибки при фильтрации данных в PHP скрипте и дать простые советы как правильно выполнить фильтрацию данных.

В сети много статей по поводу фильтрации данных, но они как правильно не полные и без подробные примеров.

Разбор полетов.

Фильтрация. Ошибка №1

Для числовых переменных используется такая проверка:

$number = $_GET['input_number'];
if (intval($number))
{
... выполняем SQL запрос ...
}


Почему она приведет к SQL инъекции? Дело в том, что пользователь может указать в переменной input_number значение:
1'+UNION+SELECT


В таком случаи проверка будет успешно пройдена, т.к. функция intval получает целочисленное значение переменной, т.е. 1, но в самой переменной $number ничего не изменилось, поэтому весь вредоносный код будет передан в SQL запрос.
Правильная фильтрация:
$number = intval($_GET['input_number']);
if ($number)
{
... выполняем SQL запрос ...
}


Конечно, условие может меняться, например если вам нужно получить только определенный диапазон:
if ($number >= 32 AND $number <= 65)



Если вы используете чекбоксы или мультиселекты с числовыми значениями, выполните такую проверку:
$checkbox_arr = array_map('intval', $_POST['checkbox']);


array_map
Так же встречаю фильтрацию в виде:
$number = htmlspecialchars(intval($_GET['input_number']));

htmlspecialchars
Или:
$number = mysql_escape_string(intval($_GET['input_number']));


mysql_escape_string

Ничего кроме улыбки это не может вызвать :)

Фильтрация. Ошибка №2.

Для стринг-переменных используется такая фильтрация:
$input_text = addslashes($_GET['input_text']);


Функция addslashes экранирует спец. символы, но она не учитывает кодировку БД и возможен обход фильтрации. Не стану копировать текст автора, который описал данную уязвимость и дам просто ссылку Chris Shiflett (перевод можно поискать в рунете).

Используйте функцию mysql_escape_string или mysql_real_escape_string, пример:
$input_text = mysql_escape_string($_GET['input_text']);


Если вы не предполагаете вхождение html тегов, то лучше всего сделать такую фильтрацию:
$input_text = strip_tags($_GET['input_text']);
$input_text = htmlspecialchars($input_text);
$input_text = mysql_escape_string($input_text);

strip_tags — убирает html теги.
htmlspecialchars — преобразует спец. символы в html сущности.
Так вы защитите себя от XSS атаки, помимо SQL инъекции.
Если же вам нужны html теги, но только как для вывода исходного кода, то достаточно использовать:
$input_text = htmlspecialchars($_GET['input_text']);
$input_text = mysql_escape_string($input_text);



Если вам важно, чтобы значение переменной не было пустой, то используйте функцию trim, пример:
$input_text = trim($_GET['input_text']);
$input_text = htmlspecialchars($input_text);
$input_text = mysql_escape_string($input_text);



Фильтрация. Ошибка №3.

Она касается поиска в БД.
Для поиска по числам используйте фильтрацию, описанную в первой ошибке.
Для поиска по тексту используйте фильтрацию, описанную во второй ошибке, но с оговорками.
Для того, чтобы пользователь не смог выполнить логическую ошибку, нужно удалять или экранировать спец. символы SQL.
Пример без доп. обработки строки:
$input_text = htmlspecialchars($_GET['input_text']); // Поиск: "%"
$input_text = mysql_escape_string($input_text);


На выходе у нас получится запрос вида:
... WHERE text_row LIKE '%".$input_text."%' ... // WHERE text_row LIKE '%%%'


Это значительно увеличит нагрузку на базу.
В своём скрипте я использую функцию, которая удаляет нежелательные мне символы из поиска:
function strip_data($text)
{
    $quotes = array ("\x27", "\x22", "\x60", "\t", "\n", "\r", "*", "%", "<", ">", "?", "!" );
    $goodquotes = array ("-", "+", "#" );
    $repquotes = array ("\-", "\+", "\#" );
    $text = trim( strip_tags( $text ) );
    $text = str_replace( $quotes, '', $text );
    $text = str_replace( $goodquotes, $repquotes, $text );
    $text = ereg_replace(" +", " ", $text);
            
    return $text;
}


Конечно, не все из выше перечисленных символов представляют опасность, но в моём случаи они не нужны, поэтому выполняю поиск и замену.
Пример использования фильтрации:
$input_text = strip_data($_GET['input_text']);
$input_text = htmlspecialchars($input_text);
$input_text = mysql_escape_string($input_text);


Также советую сделать ограничение по количеству символов в поиске, хотя бы не меньше 3-х, т.к. если у вас будет большое количество записей в базе, то поиск по 1-2 символам будет значительно увеличивать нагрузку на БД.

Фильтрация. Ошибка №4.

Не фильтруются значения в переменной $_COOKIE. Некоторые думаю, что раз эту переменную нельзя передать через форму, то это гарантия безопасности.
Данную переменную очень легко подделать любым браузером, отредактировав куки сайта.
Например, в одной известной CMS была проверка, используемого шаблона сайта:
if (@is_dir ( MAIN_DIR . '/template/' . $_COOKIE['skin'] )){
	$config['skin'] = $_COOKIE['skin'];
}
$tpl->dir = MAIN_DIR . '/template/' . $config['skin'];


В данном случаи можно подменить значение переменной $_COOKIE['skin'] и вызвать ошибку, в результате которой вы увидите абсолютный путь до папки сайта.
Если вы используете значение куков для сохранения в базу, то используйте одну из выше описанных фильтраций, тоже касается и переменной $_SERVER.

Фильтрация. Ошибка №5.

Включена директива register_globals. Обязательно выключите её, если она включена.
В некоторых ситуациях можно передать значение переменной, которая не должна была передаваться, например, если на сайте есть группы, то группе 2 переменная $group должна быть пустой или равняться 0, но достаточно подделать форму, добавив код:
<input type="text" name="group" value="5" />


В PHP скрипте переменная $group будет равна 5, если в скрипте она не была объявлена со значением по умолчанию.

Фильтрация. Ошибка №6.

Проверяйте загружаемые файлы.
Выполняйте проверку по следующим пунктам:
1. Расширение файла. Желательно запретить загрузку файлов с расширениями: php, php3, php4, php5 и т.п.
2. Загружен ли файл на сервер move_uploaded_file
3. Размер файла

Проверка. Ошибка №1.

Сталкивался со случаями, когда для AJAX запроса (например: повышение репутации) передавалось имя пользователя или его ID (кому повышается репутация), но в самом PHP не было проверки на существование такого пользователя.
Например:
$user_id = intval($_REQUEST['user_id']);
... INSERT INTO REPLOG SET uid = '{$user_id}', plus = '1' ...
... UPDATE Users SET reputation = reputation+1 WHERE user_id = '{$user_id}' ...


Получается мы создаем запись в базе, которая совершенно бесполезна нам.

Проверка. Ошибка №2.

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

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

Проверка. Ошибка №3.

При использовании нескольких php файлов сделайте простую проверку.
В файле index.php (или в любом другом главном файле) напишите такую строчку перед подключением других php файлов:
define ( 'READFILE', true );


В начале других php файлов напишите:
if (! defined ( 'READFILE' ))
{
	exit ( "Error, wrong way to file.<br><a href=\"/\">Go to main</a>." );
}


Так вы ограничите доступ к файлам.

Проверка. Ошибка №4.

Используйте хеши для пользователей. Это поможет предотвратить вызов той или иной функции путём XSS.
Пример составления хеша для пользователей:
$secret_key = md5( strtolower( "http://site.ru/" . $member['name'] . sha1($password) . date( "Ymd" ) ) ); // $secret_key - это наш хеш


Далее во все важные формы подставляйте инпут со значением текущего хеша пользователя:
<input type="hidden" name="secret_key" value="$secret_key" />


Во время выполнения скрипта осуществляйте проверку:
if ($_POST['secret_key'] !== $secret_key)
{
exit ('Error: secret_key!');
}



Проверка. Ошибка №5.

При выводе SQL ошибок сделайте простое ограничение к доступу информации. Например задайте пароль для GET переменной:
if ($_GET['passsql'] == "password")
{
... вывод SQL ошибки ...
}
else
{
... Просто информация об ошибке, без подробностей ...
}


Это позволит скрыть от хакера информацию, которая может ему помочь во взломе сайта.

Проверка. Ошибка №5.
Старайтесь не подключать файлы, получая имена файлов извне.
Например:
if (isset($_GET['file_name']))
{
include $_GET['file_name'] .'.php';
}


Используйте переключатель switch:
switch($_GET['file_name'])
{         
         case 'file_1':
         include 'file_1.php';    
         break;     
         
         default:
         include 'file_0.php';    
         break;
}


В таком случаи вы предотвратите подключение файлов, которые не были вами предусмотрены.

Совет.

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

UPD: Поправил пост. Перенес все советы по поводу функций и переменных, которые были в комментариях.

Добавлено: 19 Ноября 2021 07:27:05 Добавил: Андрей Ковальчук

Как в mysql лучше всего хранить ip адрес?

Наиболее удобно ip-адрес в MySQL хранить в типе INT. Причём обязательно UNSIGNED (беззнаковый), чтобы адреса выше 127. вполне вмещались в эти 4 байта.

`ip` int(10) unsigned NOT NULL

Тип INT более удобен для хранения ip-адресов по сравнению с CHAR(15) по двум причинам:

Требует меньше памяти (4 байта INT против 15 байт CHAR). Как результат, таблица занимает меньше места на диске, а скорость выполнения запросов возрастает, т.к. индекс меньшего размера.
Удобно производить выборки по диапазонам адресов и маскам, а также делать сортировку (получается обычная сортировка по числам).
Имеется недостаток по сравнению с хранением ip как plaintxt (char или varchar) в mysql:

Необходимость дополнительного преобразования ip-строки в число и наоборот для удобства восприятия. Для чего используются функции INET_ATON и INET_NTOA (см. дальше). Но это ведь не проблема.
Как видно, достоинства хранения ip в UNSIGNED INT сильно превосходят единственный недостаток.

Функции преобразования ip-адреса в mysql:

INET_ATON() — для преобразования IP адреса в число,
INET_NTOA() — для обратного преобразования числа в IP адрес.

Для простоты запоминания нужно знать расшифровку аббревиатуры:

ATON — Address TO Number (адрес в число),
NTOA — Number TO Address (число в адрес).

Примеры преобразования IP в mysql:
SELECT INET_NTOA(ip) FROM tablename LIMIT 10;  # выведет ip в обычном строковом формате
 
SELECT INET_ATON('127.0.0.1');    #2130706433
SELECT INET_ATON('93.125.99.10');  #1568498442
 
SELECT INET_NTOA(2130706433);   #127.0.0.1
SELECT INET_NTOA(1568498442);   #93.125.99.10

Аналогичные функции преобразования ip-адреса в PHP:

ip2long() — для преобразования IP адреса в число;
long2ip() — для обратного преобразования числа в IP адрес.
ip2long('127.0.0');     //false
ip2long('93.125.99.10'); //1568498442
ip2long('127.0.0.1');    //2130706433
ip2long('192.168.0.1'); //3232235521

long2ip('1568498442'); //93.125.99.10
long2ip('2130706433'); //127.0.0.1
long2ip('3232235521'); //192.168.0.1

Задача. Нам нужно получить все записи, которые находятся в диапазоне адресов 148.100.0.0 — 158.255.255.255. Если хранить IP в виде строк, то пришлось бы производить поиск с помощью регулярных выражений, а запрос выполнялся бы очень долго.

В случае хранения IP-адреса в типе INT sql-запрос будет таким:
SELECT .... WHERE ip BETWEEN INET_ATON('148.100.0.0') AND INET_ATON('158.255.255.255')

Добавлено: 14 Ноября 2021 07:17:57 Добавил: Андрей Ковальчук

Joker Shop Free 1.0

Выложен в свободный доступ скрипт небольшого интернет-магазина.
Как все мои бесплатные скрипты - этот тоже использует MySql для хранения информации.
В этом скрипте интернет магазина реализована пользовательская корзина.
Скачивайте, тестируйте, пользуйтесь...
Данное решение - многообещающий вариант, если у Вас есть фирма, торгующая каким-либо товаром и просто необходим свой, небольшой интернет-магазин. С помощью данного php скрипта интернет-магазина вы можете за кратчайшее время создать небольшой проект.

Что умеет скрипт:
SEO подготовленность скрипта: автоматически генерируемые мета-тэги, alt и title.
ЧПУ (Человеку_Понятные_Урлы) вида - вложенные категории. Положительно влияет для индексации поисковыми роботами
Категории неограниченной вложенности.
Поиск по заголовкам и содержанию, с подсветкой искомых слов.
Встроенный скрипт "Контакты с администрацией" с защитой от спам-ботов
Карта сайта, выводящая список ссылок на основные страница магазина
Редактирование категорий и подкатегорий (Админ часть)
Редактирование и удаление товаров (Админ часть)
Выбор количества показываемых позиций на странице

Установка:
1.Копируем файлы на сервер.
2.Импортируем дамп, который находится в файле sql_dump.sql в MySQL.
3.Редактируем файл /admin/config.php под свои настройки.
4 Если ставите скрипт в корень хоста, то строчка RewriteBase / должна остаться без изменений.
А если ставите в папку, например shop, то строчка должна выглядеть так: RewriteBase /shop/
Вход в админ часть: http://имя_домена/enter/ . Логин и пароль = admin

Добавлено: 31 Октября 2021 06:52:01 Добавил: Андрей Ковальчук

Notepad++ 6.8.8

Если вы пользователь Windows, вы наверняка знакомы с приложением «Блокнот». Это небольшой инструмент, который позволяет писать быстрые заметки. Проблема с Блокнотом заключается в том, что он очень ограничен и включает в себя меньше вариантов, которые понравятся большинству пользователей. Например, нет возможности форматировать текст или подсчитывать строки, что было бы полезно для программирования. Кроме того, поддержка формата файла очень ограничена.

К счастью, есть отличная альтернатива этому инструменту Windows, который называется Notepad ++. Вы можете узнать функциональность программы, просто взглянув на ее имя. Это улучшенная версия старого «Блокнота», в котором много новых функций и опций. Очевидно, это приложение для Windows, которое можно установить с большой легкостью и за очень короткое время.

После установки и запуска приложения пользователь будет представлен очень сложным интерфейсом, который содержит систему меню, содержащую множество опций. Первое, что пользователь заметит о программе, - это то, что каждая текстовая строка подсчитывается, что чрезвычайно полезно для программирования, если пользователь хочет быстро перейти к определенной строке или инструкции, не используя инструмент поиска. Во-вторых, программа может выделить синтаксис для различных языков программирования, таких как Java, C ++, SQL и т. Д. Практически поддерживаются самые популярные языки программирования.

Эта версия устаревшая и не являеться стабильной. Возможно по какой то причине вы решили загрузить более старую версию, но наш сайт рекомендует скачивать последнии версии программ, поскольку с каждой новой версией разработчики исправляют ошибки и проблемы с безопасностью, на данный момент актуальной версией являеться 8.1.8 - которую вы можете скачать здесь - http://notepad-plus-plus.ideaprog.download/.

На данной странице вы можете скачать программу Notepad ++ версии 6.8.8.

Разработчик: Don Ho Дата публикации: 16 Июня 2017 года Последний раз обновлено: 26 Октября 2021-года Русский язык: Есть Операционная система: Windows 10 / 8.1 / 8 / 7 / XP / Vista 32|64-bit СКАЧАТЬ
Источник: http://notepad-plus-plus.ideaprog.download/6.8.8/

Добавлено: 28 Октября 2021 13:34:31 Добавил: Андрей Ковальчук

Ajax im v3.1

Пожалуй лучший чат, который я встречал. Он подобен icq, только в браузере. Использует MySQL.
Отличается полной настраиваемостью дизайна и возможностей, но и дефолтные настройки хороши.

Добавлено: 26 Октября 2021 13:40:24 Добавил: Андрей Ковальчук