О насБлогКонтакты
Технологии5 сентября 1998 г. 5 мин 125Обновлено: 22 июня 2026 г.

Perl CGI и первые динамические сайты Кыргызстана (1998)

AunimedaAunimeda
📋 Содержание

В 1998 году интернет в Кыргызстане был роскошью. Подключение через dial-up провайдеров ElCat или Asiainfo стоило $3-5 за час - при средней зарплате в $30-50 в месяц. Пользователей интернета в стране насчитывалось несколько тысяч, сайтов с доменом .kg - единицы.

Те немногие разработчики, которые создавали сайты для государственных структур, банков или крупных компаний, неизбежно сталкивались с задачей: сделать сайт «живым». Форма обратной связи, гостевая книга, новости из базы данных - всё это требовало CGI. И писали его на Perl.


Первая гостевая книга для бишкекского сайта

#!/usr/bin/perl
# guestbook.pl - гостевая книга, Бишкек, 1998 год
# Сервер: Unix/Linux где-то в Германии или Москве
# Кодировка: windows-1251

use strict;
use warnings;
use CGI;
use POSIX qw(strftime);

my $DATA_FILE   = '/home/mysite/data/guestbook.txt';
my $MAX_ENTRIES = 75;

my $cgi    = new CGI;
my $action = $cgi->param('action') || 'view';

if ($action eq 'post') {
    post_entry($cgi);
} else {
    show_entries($cgi);
}

sub post_entry {
    my ($q) = @_;

    my $name    = $q->param('name')    || '';
    my $email   = $q->param('email')   || '';
    my $message = $q->param('message') || '';
    my $from    = $q->param('from')    || '';   # Откуда (город/страна)

    # Базовая очистка
    for my $f ($name, $email, $message, $from) {
        $f =~ s/[<>&"'\\]//g;
        $f =~ s/[\r\n]+/ /g;
    }

    if (length($name) < 2 || length($message) < 3) {
        print_header();
        print "<p><font color=red>Введите имя и сообщение!</font></p>\n";
        print "<a href='guestbook.pl'>Назад</a>\n";
        print_footer();
        return;
    }

    my $ts = strftime('%d.%m.%Y %H:%M', localtime);

    my @entries = load_file();
    unshift @entries, join('|', $name, $email, $from, $message, $ts);
    @entries = @entries[0..$MAX_ENTRIES-1] if @entries > $MAX_ENTRIES;
    save_file(\@entries);

    print "Content-Type: text/html; charset=windows-1251\n\n";
    print "<html><head><meta http-equiv=refresh content='0;url=guestbook.pl'></head>";
    print "<body>Записано! <a href=guestbook.pl>Открыть</a></body></html>";
}

sub show_entries {
    my ($q) = @_;
    print_header();

    print "<h2>Написать в гостевую книгу</h2>\n";
    print "<form method=POST action=guestbook.pl>\n";
    print "<input type=hidden name=action value=post>\n";
    print "<table border=0 cellpadding=5>\n";
    print "<tr><td>Имя: *</td><td><input name=name size=28></td></tr>\n";
    print "<tr><td>E-mail:</td><td><input name=email size=28></td></tr>\n";
    print "<tr><td>Откуда:</td><td><input name=from size=28></td></tr>\n";
    print "<tr><td valign=top>Текст: *</td>";
    print "<td><textarea name=message rows=4 cols=38></textarea></td></tr>\n";
    print "<tr><td></td><td><input type=submit value='Отправить'></td></tr>\n";
    print "</table></form>\n";
    print "<hr>\n<h2>Записи</h2>\n";

    my @entries = load_file();
    if (!@entries) {
        print "<p><i>Записей нет. Будьте первым!</i></p>\n";
    }

    for my $line (@entries) {
        my ($name, $email, $from, $msg, $ts) = split /\|/, $line;
        print "<p><b>$name</b>";
        print " ($from)" if $from;
        print " &mdash; <i>$ts</i><br>$msg</p><hr size=1>\n";
    }

    print_footer();
}

sub load_file {
    my @lines;
    return @lines unless -f $DATA_FILE;
    open my $fh, '<', $DATA_FILE or return @lines;
    @lines = grep { /\S/ } <$fh>;
    chomp @lines;
    close $fh;
    return @lines;
}

sub save_file {
    my ($lines) = @_;
    open my $fh, '>', $DATA_FILE or die "Не могу записать: $!";
    print $fh "$_\n" for @$lines;
    close $fh;
}

sub print_header {
    print "Content-Type: text/html; charset=windows-1251\n\n";
    print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
    print "<html><head><title>Гостевая книга</title></head>\n";
    print "<body bgcolor=#FFFFFF>\n";
    print "<h1>Гостевая книга</h1>\n";
}

sub print_footer {
    print "<hr><small>Бишкек &bull; 1998 &bull; Perl CGI</small>\n";
    print "</body></html>\n";
}

Реалии деплоя в Бишкеке 1998 года

Запустить CGI-скрипт в 1998 году из Бишкека означало несколько практических сложностей:

Хостинг за рубежом. В Кыргызстане практически не было коммерческих хостинг-провайдеров. Сайты размещались в России (Zenon, Demos, Cityline) или Европе (немецкие провайдеры). Это означало:

  • Все настройки - через FTP и Telnet из Бишкека
  • Задержка (ping до Москвы ~60-80 мс, до Европы ~120-180 мс)
  • Техподдержка работала в московском или европейском часовом поясе
# Стандартный workflow деплоя из Бишкека в 1998:

# 1. Написать скрипт в Windows 95/98 (Блокнот или UltraEdit)
# ВАЖНО: сохранить с Unix-переносами строк! Иначе ошибка 500.
# UltraEdit умел конвертировать: File -> Conversions -> DOS to Unix

# 2. Загрузить по FTP в ASCII-режиме (не бинарный!)
# WS_FTP LE - бесплатная FTP-программа, стандарт 1998 года
# Binary режим испортит скрипт: FTP должен конвертировать CRLF -> LF

# 3. Подключиться по Telnet и выставить права
telnet myhost.com
chmod 755 /home/mysite/cgi-bin/guestbook.pl
chmod 777 /home/mysite/data/   # не очень безопасно, но иначе никак

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

# ПРАВИЛЬНО - две строки: заголовок + пустая строка
print "Content-Type: text/html\n\n";

# НЕПРАВИЛЬНО - одна строка без пустой строки после
print "Content-Type: text/html\n";   # браузер не поймёт тело ответа

Кодировка и кыргызский язык

В 1998 году добавить кыргызский текст на сайт было практически невозможно технически. Специфические кыргызские буквы (Ң, Ү, Ө, Ё) не входили ни в windows-1251, ни в KOI8-R полностью.

# В Perl 1998 года для кыргызского/русского текста:
print "Content-Type: text/html; charset=windows-1251\n\n";

# Кыргызский текст: либо транслитерация, либо обходились русским
# Буква Ң в windows-1251 отсутствует → писали НГ или избегали

# KOI8-R - вариант для Unix-серверов:
# use Encode;
# my $text = Encode::encode('koi8-r', Encode::decode('cp1251', $win_text));

Полноценный кыргызский язык в вебе появился только с переходом на UTF-8 - примерно к 2006-2008 годам, когда браузеры и серверы наконец стандартизировались на Unicode.


Путь от Perl к PHP в кыргызнете

К 2001-2002 году PHP 4 вытеснил Perl как инструмент веб-разработки и в Кыргызстане. Причины были теми же, что и в остальном русскоязычном интернете:

  1. Простота деплоя: .php файлы работали как обычные веб-страницы
  2. Русскоязычная документация: php.net/ru, статьи на phpclub.ru
  3. Хостинг с PHP: российские хостинги добавили поддержку PHP раньше, чем улучшили поддержку Perl CGI

Тем не менее, навыки Perl CGI, полученные в 1998-2000 годах, дали бишкекским разработчикам понимание, которого нельзя получить иначе: как веб-сервер запускает программы, как работает HTTP на уровне заголовков, как хранить состояние без базы данных. Эти знания не устарели - они просто стали невидимы за слоями абстракций современных фреймворков.

Читайте также

Как мы используем ИИ в разработке в Бишкеке: делаем за 2 недели то, что раньше занимало 2 месяцаaunimeda
Технологии

Как мы используем ИИ в разработке в Бишкеке: делаем за 2 недели то, что раньше занимало 2 месяца

Честно о том, как Aunimeda использует искусственный интеллект в разработке сайтов и приложений. Что это даёт клиентам в Кыргызстане и почему это меняет рынок.

Первые сайты на PHP3 в 2002: как мы верстали до CSS, без фреймворков и без Stack Overflowaunimeda
Технологии

Первые сайты на PHP3 в 2002: как мы верстали до CSS, без фреймворков и без Stack Overflow

В 2002 году не было CSS Zen Garden, не было jQuery, не было документации на русском. Был PHP 3/4, были таблицы для вёрстки, был Dreamweaver с WYSIWYG, и было сообщество на форуме phpclub.ru. Вот как выглядела реальная веб-разработка 20 лет назад.

DHTML-навигация в Бишкеке 2001 года: выпадающие меню на чистом JavaScriptaunimeda
Технологии

DHTML-навигация в Бишкеке 2001 года: выпадающие меню на чистом JavaScript

В 2001 году выпадающее меню без Flash и без перезагрузки страницы - это было то, что отличало профессиональный бишкекский сайт от любительского. DHTML на JavaScript + CSS. Работало в IE5 и Netscape 6. Вот как мы это делали, что ломалось и почему 300 мс до сих пор актуально.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в Кыргызстане. Бесплатная консультация.

Получить консультацию Все статьи