Фильтрация и проверка данных 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 Добавил: Андрей Ковальчук

Выборка за месяц, неделю

Да очень просто:

Выборка за текущий месяц:

select id from tab where date_format(real_time, '%Y%m') = date_format(now(), '%Y%m');

или вот так:
select id from tab where month(real_time) = month(now()) and year(real_time) = year(now());


За прошлый месяц:
select id from tab where date_format(real_time, '%Y%m') = date_format(date_add(now(), interval -1 month), '%Y%m');


За текущую неделю:
select id from tab where year(real_time) = year(now()) and week(real_time, 1) = week(now(), 1);


В функции week(date, N) N - это номер дня, с которого начинается неделя: 0 - с воскресенья, 1 - с понедельника

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

select id 
from tab 
where real_time > LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 1 MONTH))
  AND real_time < DATE_ADD(LAST_DAY(CURDATE()), INTERVAL 1 DAY)


за предыдущий
select id 
from tab 
where real_time > LAST_DAY(DATE_SUB(CURDATE(), INTERVAL 2 MONTH))
  AND real_time < DATE_ADD(LAST_DAY(CURDATE() - INTERVAL 1 MONTH), INTERVAL 1 DAY)


за текущую неделю
select id 
from tab 
where real_time > DATE_SUB(CURDATE(), INTERVAL (DAYOFWEEK(CURDATE()) -1) DAY)
  AND real_time < DATE_ADD(CURDATE(), INTERVAL (9 - DAYOFWEEK(CURDATE())) DAY)

Добавлено: 09 Июня 2021 06:22:07 Добавил: Андрей Ковальчук

Поиск по базе данных (php + mysql).

Задача: осуществить поиск по базе данных на php. В качестве входного параметра – строка (одно или несколько слов, числа …).

Решение: используем оператор LIKE в SQL-запросе.

Примеры:

1. Определяем количество строк в таблице, где есть совпадения с $squery по искомой строке:

$sql = "SELECT COUNT(*) FROM products WHERE (product_name LIKE '%$squery%' OR description LIKE '%$squery%')";

2. Получаем все строки из таблицы, где есть совпадения с $squery.
$sql =  "SELECT * FROM products WHERE (product_name LIKE '%$squery%' OR description LIKE '%$squery%') LIMIT $start, $limit";

Добавлено: 18 Мая 2018 07:32:50 Добавил: Андрей Ковальчук

Живой поиск

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

Подключаем фреймворк jquery, если он еще не подключен. Далее у нас будет простая форма всего с одним полем. Именно в нем мы будем отслеживать изменение поискового запроса и сразу же отображать нужный результат.

<form action="search.php" method="post" name="form" onsubmit="return false;">
  <p>
    Живой поиск:<br> 
    <input name="search" type="text" id="search">
    <small>Вводите на английском языке</small>
  </p>
</form>

Сразу за формой разместим блок, в котором будут отображаться результаты поиска
<div id="resSearch">Начните вводить запрос</div>

Теперь посмотрим основную часть кода. Как ни странно, но она очень простая и представляет всего несколько строк кода:
<script type="text/javascript">
$(function(){
  $("#search").keyup(function(){
     var search = $("#search").val();
     $.ajax({
       type: "POST",
       url: "search.php",
       data: {"search": search},
       cache: false,                                 
       success: function(response){
          $("#resSearch").html(response);
       }
     });
     return false;
   });
});
</script>

Как видите все довольно просто. Мы просто отслеживаем любое изменение содержимого в поле сid=search, получаем это значение и отправляем нашему обработчику search.php, производящий собственно сам поиск. Далее любой результат, который мы получили от обработчика мы просто выводим в блок с id=research.

Теперь поговорим, как устроен обработчик. Как правило, поиск производится по базе данных, но в примере мы будем искать в массиве название стран (в исходниках приведен код для поиска по базе данных). Не забывайте о том, что когда поиск производится по базе данных, то у поля, по которому мы ищем должен быть режим «полный текст».
<?php
header("Content-type: text/html; charset=windows-1251");
$search = $_POST['search'];
$search = addslashes($search);
$search = htmlspecialchars($search);
$search = stripslashes($search);
   if($search == ''){
      exit("Начните вводить запрос");
   }
$db = mysql_connect("localhost","user","password");
mysql_select_db("basa",$db);
mysql_query("SET NAMES cp1251");
                
$query = mysql_query("SELECT * FROM table WHERE MATCH(text) AGAINST('$search')",$db);
if(mysql_num_rows($query) > 0){
   $sql = mysql_fetch_array($query);
   do{
     echo "<div>".$sql['text']."</div>";
   }while($sql = mysql_fetch_array($query));
}else{
   echo "Нет результатов";
}
?>

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

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

Добавлено: 17 Мая 2018 19:45:19 Добавил: Андрей Ковальчук

sqlsrv_encoding_utf8

В базах данных от Microsoft очень часто наблюдаются проблемы с кодировкой. Данные нужно переводить из windows-1251 в UTF-8.
Это делается на уровне базы данных.Можно использовать функцию PDO::SQLSRV_ENCODING_UTF8 для драйвера PDO.Очень удобный драйвер для общения с любой базой данных.

$serverName = "serverName\SQLEXPRESS"; 
$name= "user_name"; 
$pass = "password"; 
$options = array(PDO::SQLSRV_ATTR_ENCODING=>PDO::SQLSRV_ENCODING_UTF8, "CharacterSet" => "UTF-8");  
 
try 
{ 
    $conn = new PDO( "sqlsrv:Server=".$serverName."; Database=DB_Name", $name, $pass, $options); 
    echo "Connected!"; 
} 
catch(Exception $e) 
{ 
    die( print_r( $e->getMessage() ) ); 
}

Или устанавливать атрибут при соединении с БД
$conn->setAttribute(PDO::SQLSRV_ATTR_ENCODING, PDO::SQLSRV_ENCODING_UTF8); 

Если перебороть эту напасть не удастся-можно использовать iconv на стороне php сервера.

Если и это не поможет-смените тип поля с varchar на nvarchar.Должно помочь.

Добавлено: 17 Мая 2018 11:26:32 Добавил: Андрей Ковальчук

Работа с запросами SQL в PHP с помощью ezSQL

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

Что такое ezSQL, и зачем он нужен
В больших проектах обычной практикой является использование CMS или рабочей среды, например, Symfony или CodeIgniter, для построения структуры сайта. Но в маленьких проектах очень многие разработчики продолжают использовать функции PHP, такие как mysql_query(), для организации запросов SQL к базе данных.

Не смотря на функциональность такого подхода, использование всех функций вида mysql_XXX является порочным методом работы. Конечно, очень многие сайты используют MySQL, но если в один прекрасный день придется иметь дело с какой-нибудь другой базой данных, например PostGres или Oracle… Ваш код не будет работать и придется переписывать все практически с нуля. Очень печально, не так ли? Поэтому рекомендуется использовать уровень абстрагирования базы данных, то есть API, которая будет обеспечивать коммуникацию между вашим приложением/веб сайтом и сервером базы данных, будь то MySQL, Oracle или PostgreSQL.

Как вы наверно же догадались, ezSQL позволяет работать с большим количеством различных баз данных одинаково легко. Хотя нужно отметить, что она не поддерживает разницу в реализации синтаксиса SQL среди различных баз данных.

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

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

Загрузка и установка ezSQL
Сделаем несколько примеров. Для начала надо скачать копию ezSQL (ищем на открывшейся странице ссылку "Download ezSQL"). После загрузки архива, распаковываем его в папку проекта на сервере.

Для того чтобы использовать ezSQL в своих проектах, надо включить два файла: первый - ez_sql_core.php (ядро ezSQL); второй зависит от типа используемой в вашем проекте базы данных. Чтобы использовать ezSQL для MySQL, нужно включить файл ez_sql_mysql.php.

После включения файлов нужно создать объект ezSQL. Это легко выполняется с указанием имени базы данных, имени пользователя, его пароля и сервера базы данных. Следующий пример демонстрирует включение требуемых файлов и создание объекта ezSQL:

include_once "../shared/ez_sql_core.php";
include_once "ez_sql_mysql.php";
$db = new ezSQL_mysql('имя_пользователя_БД','пароль_пользователя_БД','имя_БД','сервер_БД');

Теперь у нас есть объект $db. И его можно использовать для выполнения запросов к базе данных.

Примеры запросов
ezSQL имеет несколько методов для простой организации SQL запросов. Рассмотрим несколько примеров:

Выполнение любого запроса
Для того чтобы выполнить любой запрос к базе данных, нужно использовать метод query. В случае добавления данных метод вернет идентификатор добавленной записи.
$db->query("INSERT INTO users (id, name, email) VALUES (NULL,'Кошка','cat@google.com')");

Пример запроса обновления данных:
$db->query("UPDATE users SET name = 'Петруха' WHERE id = 4");

Выбор строки
Метод get_row используется для извлечения строки из базы данных. В примере выполняется запрос, и выводятся полученные данные:
$user = $db->get_row("SELECT name, email FROM users WHERE id = 4");
 
echo $user->name;
echo $user->email;

Выбор одной переменной
Если вам нужно только одна переменная, то в данном случае подходит метод get_var. Его очень просто использовать:
$var = $db->get_var("SELECT count(*) FROM users");
 
echo $var;

Выбор множества строк
Большой объем работы с данными приходится на получение из базы нескольких строк, соответствующих определенному критерию, и их обработку. Метод get_results позволяет получить различные данные из базы. Для обработки используется цикл foreach():
$results = $db->get_results("SELECT name, email FROM users");
 
foreach ( $results as $user ) {
    echo $user->name;
    echo $user->email;
}

Выбор столбца
Если нужно получить столбец, то можно воспользоваться методом get_col. Второй параметр - это смещение столбца в результате запроса.
foreach ( $db->get_col("SELECT name,email FROM users",0) as $name ) {
            echo $name;
}

Отладка
Когда что-то не работает так, как ожидалось, ezSQL имеет отличный метод для выполнения отладки. Очевидно, что метод называется debug. При вызове данный метод отображает последний выполненный запрос к базе данных и его результат:
$db->debug();

Надеюсь, что ezSQL поможет вам в успешной реализации ваших будущих проектов!

Добавлено: 16 Мая 2018 09:14:39 Добавил: Андрей Ковальчук

PHP+MySQL проблемы с кодировкой

На некоторых хостингах возникают проблемы с кодировкой – символы отображаются знаками вопроса или иероглифами. Очень часто по причине того что созданная таблица или база данных не состыкуется с кодировкой самого сайта. То есть к примеру вы используете cp1251 (стандартную кодировку для русских символов Windows-1251) а база под кодировкой utf-8 или на оборот.

Как вариант решения:

mysql_query ("set character_set_client='cp1251'") || die(mysql_error());
mysql_query ("set character_set_results='cp1251'") || die(mysql_error());
mysql_query ("set collation_connection='cp1251_general_ci'");

это запросы из php которые следует применять После подключения к базе. И эти запросы если применяются то должны применятся при выводе данных и при внесении данных в БД

Добавлено: 08 Мая 2018 21:30:28 Добавил: Андрей Ковальчук

Импорт больших SQL-дампов через PHP

Основная проблема при импорте большого SQL-дампа — нехватка памяти при чтении всего дампа. Решение очевидно: грузить в память только то, что нужно в данный момент.

$f = @fopen("path/to/dump.sql", "r");
if($f)
{
    $q = '';
 
    while(!feof($f))
    {
        // читаем построчно в буфер $q      
        $q .= fgets($f);
 
        // пока не упрёмся в ;
        if(substr(rtrim($q), -1) == ';')
        {
            // выполяем запрос
            execute_sql($q);
 
            // обнуляем буфер
            $q = '';
        }
    }
}

Добавлено: 07 Мая 2018 06:47:11 Добавил: Андрей Ковальчук

Изменяем адрес URL изображений

Если нужно поменять путь к вашим изображениям, вы можете использовать следующий запрос SQL (замените http://www.myoldurl.com на старый адрес папки с изображениями, а http://www.mynewurl.com - на новый адрес):

UPDATE wp_posts
SET post_content = REPLACE (post_content, 'src=”http://www.myoldurl.com', 'src=”http://www.mynewurl.com');

Добавлено: 02 Мая 2018 11:36:50 Добавил: Андрей Ковальчук

Поиск и замена содержания записи

Для поиска и замены содержания записи используйте следующий запрос. Замените ‘OriginalText‘ текстом, который надо найти, а ‘ReplacedText‘ - новым текстом.

UPDATE wp_posts SET `post_content`
= REPLACE (`post_content`,
'OriginalText',
'ReplacedText');

Добавлено: 02 Мая 2018 11:36:10 Добавил: Андрей Ковальчук

Переустанавливаем пароль вручную

Если вы единственный пользователь вашего блога WordPress и имя пользователя admin, то можно изменить пароль с помощью запроса SQL. Нужно заменить PASSWORD на новый пароль:

UPDATE `wordpress`.`wp_users` SET `user_pass` = MD5('PASSWORD') WHERE `wp_users`.`user_login` =`admin` LIMIT 1;

Добавлено: 02 Мая 2018 11:35:32 Добавил: Андрей Ковальчук

Пакетное удаление ревизий записей

Ревизии записей могут быть весьма полезными, но они существенно увеличивают размер базы MySQL. Можно удалять ревизии записей вручную, но значительно быстрее будет использовать запрос SQL.

DELETE FROM wp_posts WHERE post_type = "revision";

Добавлено: 02 Мая 2018 11:34:44 Добавил: Андрей Ковальчук

Делаем запись страницей и наоборот

Сделать запись страницей очень просто:

UPDATE wp_posts SET post_type = 'page' WHERE post_type = 'post'

А если нужно выполнять обратную задачу, используем запрос:
UPDATE wp_posts SET post_type = 'post' WHERE post_type = 'page'

Добавлено: 02 Мая 2018 11:34:01 Добавил: Андрей Ковальчук

Удаляем ненужный короткий код

Короткий код WordPress является отличным инструментом, но когда он становится ненужным записи все равно продолжают хранить его. Данный запрос удаляет ненужный короткий код из базы данных. Замените ‘tweet‘ на имя короткого кода, который надо удалить.

UPDATE wp_post SET post_content = replace(post_content, '[tweet]', '' ) ;

Добавлено: 02 Мая 2018 11:33:19 Добавил: Андрей Ковальчук