В 2002 году интернет в Кыргызстане был у немногих - в основном корпоративные клиенты и государственные организации в Бишкеке. Elcat, AsiaInfo, KyrgyzTelecom предоставляли подключение. Dial-up был нормой, выделенные линии - роскошью.
Но сайты делали. Корпоративные визитки, первые государственные порталы, каталоги компаний. Технологический выбор был прост: LAMP.
Windows Server + SQL Server + ASP требовал лицензий и дорогого хостинга. LAMP стоил ноль. Shared-хостинг с Apache, MySQL и PHP у российских провайдеров (masterhost.ru, valuehost.ru) стоил $5-15 в месяц. Для бишкекского клиента 2002 года - разница принципиальная.
PHP 4: язык, которым строился бишкекский веб
<?php
// config.php - стандарт 2002 года в Бишкеке
// PHP 4.x, MySQL 3.23/4.0, Apache 1.3
define('DB_HOST', 'localhost');
define('DB_USER', 'siteuser');
define('DB_PASS', 'pass123');
define('DB_NAME', 'bishkek_site');
$db = mysql_connect(DB_HOST, DB_USER, DB_PASS)
or die('Ошибка подключения: ' . mysql_error());
mysql_select_db(DB_NAME, $db)
or die('Нет базы: ' . mysql_error());
// Кодировка - вечная боль 2002 года в Кыргызстане
// Сайты были в cp1251 или koi8-r, юникод только начинался
mysql_query("SET NAMES 'cp1251'", $db);
// register_globals = On по умолчанию в PHP 4
// $_GET['id'] автоматически становился $id
// Это было главной уязвимостью бишкекских сайтов
?>
<?php
// news.php - новостной раздел типичного бишкекского сайта 2002
require_once 'config.php';
$page = isset($_GET['p']) ? max(1, intval($_GET['p'])) : 1;
$limit = 15;
$off = ($page - 1) * $limit;
// Категория - если есть
$cat = isset($_GET['cat']) ? intval($_GET['cat']) : 0;
$where = $cat > 0 ? "WHERE category_id = $cat" : "";
$total = mysql_fetch_row(
mysql_query("SELECT COUNT(*) FROM news $where", $db)
);
$pages = ceil($total[0] / $limit);
$res = mysql_query(
"SELECT id, title, text, date_add
FROM news $where
ORDER BY date_add DESC
LIMIT $off, $limit", $db
);
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Новости компании</title>
<link rel="stylesheet" href="/style.css" type="text/css">
</head>
<body>
<table width="760" border="0" cellspacing="0" align="center">
<tr><td>
<?php while ($row = mysql_fetch_assoc($res)): ?>
<div class="news-item">
<h3><a href="news_item.php?id=<?php echo $row['id']; ?>">
<?php echo htmlspecialchars($row['title']); ?>
</a></h3>
<p class="date"><?php echo date('d.m.Y', strtotime($row['date_add'])); ?></p>
<p><?php echo nl2br(htmlspecialchars(substr($row['text'], 0, 200))); ?>...</p>
</div>
<?php endwhile; ?>
<?php if ($pages > 1): ?>
<div class="pagination">
<?php for ($i = 1; $i <= $pages; $i++): ?>
<?php if ($i == $page): ?>
<strong><?php echo $i; ?></strong>
<?php else: ?>
<a href="?p=<?php echo $i; ?><?php echo $cat ? "&cat=$cat" : ''; ?>">
<?php echo $i; ?>
</a>
<?php endif; ?>
<?php endfor; ?>
</div>
<?php endif; ?>
</td></tr>
</table>
</body>
</html>
Apache .htaccess: что знал каждый бишкекский разработчик
# .htaccess - обязательное знание 2002 года
RewriteEngine On
# Красивые URL:
RewriteRule ^novosti/([0-9]+)/?$ news_item.php?id=$1 [L,QSA]
RewriteRule ^katalog/([a-z0-9-]+)/?$ catalog.php?slug=$1 [L,QSA]
# Безопасность - обязательно:
php_flag register_globals Off
php_flag display_errors Off
php_value error_log /home/user/logs/php_errors.log
Options -Indexes
# Защита конфигов:
<FilesMatch "\.(php\.bak|sql|log)$">
Order allow,deny
Deny from all
</FilesMatch>
SQL-инъекции: главная уязвимость 2002 года
<?php
// Это делали почти все в Бишкеке в 2002 - УЯЗВИМО:
$id = $_GET['id']; // register_globals: просто $id после включения
$res = mysql_query("SELECT * FROM products WHERE id = $id");
// URL: ?id=1 OR 1=1-- → возвращает все записи
// Правильно (минимальная защита):
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id <= 0) { header('Location: /'); exit; }
// Для строковых параметров:
$search = mysql_real_escape_string(
isset($_GET['q']) ? $_GET['q'] : ''
);
$res = mysql_query(
"SELECT * FROM products
WHERE name LIKE '%$search%' AND active = 1
LIMIT 50", $db
);
// PDO с параметрами появится в PHP 5.1 (2005).
// До тех пор - ручное экранирование.
// Многие бишкекские сайты 2002-2005 были уязвимы.
?>
Почему LAMP победил в Бишкеке
Цена - решающий фактор. Лицензии Microsoft были недоступны большинству клиентов. LAMP бесплатен.
Хостинг - российские провайдеры давали PHP+MySQL за $5-10/мес. Местного хостинга с таким уровнем почти не было.
Документация по-русски - php.net переводился, на форумах (phpclub.ru, webmasters.ru) отвечали по-русски. Бишкекские разработчики учились у российских коллег.
К 2005 году LAMP работал в основе почти всех коммерческих сайтов Кыргызстана. Корпоративные порталы, первые интернет-магазины, государственные сайты - всё на Apache и PHP.