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

Напоминаю ссылку на репозиторий фреймворка: https://github.com/O-Planet/LOTIS

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

  • Синхронизацию данных между клиентом и сервером

  • Управление состоянием

  • Написание идентичной логики на двух языках

  • Обработку AJAX-запросов

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

? История появления: для чего

Я являюсь фрилансером, не совместителем по вечерам, а именно фрилансером. У меня нет «основного» места работы, нет директора. Я сам ищу заказчиков, веду переговоры, заключаю договора, сам выполняю проекты, внедряю, обучаю.  Занимаюсь этим уже более 20-и лет. Отсюда и возникла потребность в фреймворке «все – в одном» для быстрой разработки WEB-приложений, ведь большинству заказчиков результат нужен «еще вчера». Поэтому, скорость разработки – первый критерий для моей успешной работы.

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

Но если кто-то думает, что фрилансеру-одиночке отдают только проекты вроде лендингов, то спешу разочаровать: к услугам фрилансеров обращаются сети Duty Free, производственные комбинаты, логистические компании, сети ресторанов, супермаркета, частные медицинские клиники, предприятия оборонной промышленности. И задачи у них объемные. Поэтому, третье требование к моему подручному инструменту – возможность оперировать объектами и сущностями предметной области бизнес процессов, такими, как справочник, документ с несколькими табличными частями, отчеты, стоки и коллекторы данных, устойчивый многопользовательский режим, подкачка из базы данных, реактивность…

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

Так и появилась идея создания фреймворка LOTIS (Low Time Script), его первые, неудачные релизы и текущая, стабильная версия. История длиною в десять лет.

⭐ Основные отличительные особенности LOTIS

  • Фреймворк для быстрой разработки сложных бизнес-приложений одним разработчиком или небольшой командой

  • Единое функциональное пространство: линейная логика, без разделения на клиент/сервер

  • Работа с объектами бизнес-логики, а не с DOM-элементами

  • Отсутствие необходимости писать HTML вручную: приложение строится на классах

LOTIS реализует модель CMA (Construct – Metadata - Assembly)

┌───────────┐     ┌───────────┐     ┌───────────┐
│           │     │           │     │           │
│  CONSTRUCT│────>│ METADATA  │────>│ ASSEMBLY  │
│           │     │           │     │           │
└───────────┘     └───────────┘     └───────────┘
     │                  │                  │
     │ Создание         │ Генерация        │ Преобразование
     │ объектной модели │ структурирован-  │ метаданных
     │                  │ ных данных       │ в DOM
     ▼                  ▼                  ▼
  Объекты          Массивы данных     Готовый интерфейс
  PHP/JS           (тип, id, свойства)  в браузере

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

Традиционный подход

LOTIS (CMA)

Разделение на клиент/сервер

Единое функциональное пространство

Работа с DOM-элементами

Работа с объектами бизнес-логики

Написание HTML вручную

Автоматическая генерация через метаданные

Сложные AJAX-запросы

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

? Объектная модель LOTIS

┌─────────┐    ┌───────────┐    ┌──────────┐    ┌───────────┐    ┌───────────┐
│  Ether  │ ←─ │ Construct │ ←─ │   Quark  │ ←─ │  Element  │ ←─ │   Space   │
└─────────┘    └───────────┘    └──────────┘    └───────────┘    └───────────┘
 Интерфейс      Базовый цикл    Управление      HTML-специфика     Сборка DOM
 контракта      и идентификаторы потомками       и метаданные    по метаданным
  1. Ether определяет методы жизненного цикла объекта

  2. Construct управляет жизненным циклом объекта

  3. Quark добавляет систему хранения данных и работу с потомками

  4. Element специализируется на визуальных компонентах

  5. Space выполняет сбор метаданных и построкение DOM

Методы жизненного цикла

  • compile – предварительная обработка до генерации метаданных

  • shine – генерация метаданных

  • addinspace – добавление метаданных во вселенную

  • childs – обход потомков объекта и запуск для них create

  • create – полный жизненный цикл.

Жизненный цикл объекта

┌───────────┐   ┌───────────┐   ┌───────────┐   ┌───────────┐
│   check   │ → │   before  │ → │   shine   │ → │ addinspace│
└───────────┘   └───────────┘   └───────────┘   └───────────┘
        │
        └───▶ [прекращение построения]

┌──────────────┐   ┌─────────────┐   ┌───────────┐   ┌───────────┐
│ checkchilds  │ → │ beforechilds│ → │   childs  │ → │  onchilds │
└──────────────┘   └─────────────┘   └───────────┘   └───────────┘
        │
        └───▶ [прекращение построения потомков]

┌───────────┐
│    on     │
└───────────┘

Метаданные – это структурированное описание объекта в виде массива:

Пример:

[
    'type' => 'html',
    'id' => 'O5',
    'tagname' => 'div',
    'class' => 'my-class',
    'attr’ => ['data-role' => 'button', 'disabled' => true],
    'caption' => 'Кнопка',
    'parent' => 'O4'
]

⚡ Уникальные возможности архитектуры

Единая точка входа

Мне не хотелось использовать composer и подобные инструменты. Я задался целью минимизировать порог вхождения в фреймворк и сделать его максимально легким. Решением стала реализация фабричного абстрактного класса LTS, ставшего единой точкой входа.

Ключевые особенности:

  1. Автоматически подключает все классы по мере их использования в приложении при помощи spl_autoload_register

  2. Предоставляет фабричные методы для создания объектов: LTS::Form, LTS::Grid, LTS::Events и т.д. всего 41 класс.

  3. Для подключения фреймворка необходимо подключить к проекту только один единственный файл: lotis.php:

include_once 'newlotis/lotis.php';

Единое пространство переменных

В LOTIS вы можете не только помещать последовательно клиентский и серверный код в один файл, но также использовать одни те же переменные в PHP и JavaScript. Это серьезно облегчает разработку:

$mygrid = LTS::Grid();
$mybutton = LTS::Button()
	->capt('Переключить')
    ->click(<<<JS 
  LTS(mygrid).mode('content'); // Вызов клиентского метода mode класса Grid
  $(mybutton).hide(); 	       // Вызов jQuery-метода hide
JS);

События без Ajax

Класс Events позволяет организовать клиент-серверное взаимодействие как единый поток:

// Определение события
$myevents = LTS::Events()
	->client('hello(name)', <<<JS alert(result); JS)
	->server('hello', function ($args) {
		$name = $args['name'];
		return "Hello, {$name}!";
});
//Вызов события на клиенте:
$nameinput = LTS::Input()->text('myname', 'Ваше имя');
LTS::Button()
	->capt('Выполнить')
	->click(<<<JS
		LTS(myevents).hello($(nameinput).val());
	JS);

Сигналы

Для организации управления клиентскими объектами предусмотрены сигналы оповещения и подписки на них:

// Подписка:
$myelement->signal('hideAll', <<<JS
    $(myelement).hide();
JS);
// Оповещение:
$mybutton->click(<<<JS LTS.signal('hideAll'); JS);

Клиентские методы

Функциональность любого объекта может быть расширена клиентскими методами.

$mydiv = LTS::Div()->method('hello', <<<JS alert('Hello, world!'); JS);

Глобальные переменные

Класс Vars предназначен для синхронизации данных при клиент-серверном взаимодействии без участия программиста.

// На сервере
$vars = LTS::Vars();
$value = $vars->get('counter'); 
// На клиенте
let counter = LTS.vars().get('counter');
LTS.vars().set('counter', ++counter).store();

Поставка без исходного кода

Архитектура CMA позволяет:

  • Сохранять только метаданные (не исходный код)

  • Загружать приложение из сериализованного массива

  • Увеличить скорость загрузки

  • Защитить авторские права

? Примеры использования классов фреймворка

Построение иерархии

Вы создаете объектную модель интерфейса, а не HTML-разметку. Нет необходимости думать о том, как это будет выглядеть в DOM — фреймворк позаботится об этом.

$content = LTS::Div()->columnbox();
$header = LTS::Div()->rowbox()->height('50px');
$header->addmany(LTS::Button()->capt('Button 1'), LTS::Button()->capt('Button 2'));
$body = LTS::Div()->flex();
$body->css('background', '#000000')->css('color', '#ffffff')->capt('Body content …');
$footer = LTS::Div()->height('50px')->capt('Footer');
$content->addmany($header, $body, $footer);
LTS::Space()->build($content);

Работа с формами

Логика формы и обработчики для кнопок находятся в одном месте.

// Создание формы
$myform = LTS::Form();

// Добавление полей
$myform->text('username', 'Логин')
     ->password('password', 'Пароль')
     ->email('email', 'Email');

// Добавление кнопок
$myform->button('close', 'Закрыть')->click(<<<JS $(myform).hide() JS);
$clickbutton = $myform->button('clickme', 'Нажми меня');

// Привязка события к кнопке
$myform->event($clickbutton, <<<JS
    alert(result);
JS)
  ->event($clickbutton, function($args) {
    return 'Привет, ' . $args['username'];
});

Таблицы

Вы работаете с таблицами, как с объектами, определяя состав колонок, содержимое, сортировку строк. Вы можете динамически подкачивать, обновлять данные таблицы без перерисовки DOM.

// Создание базовой таблицы
$table = LTS::DataTable()
    ->head(['name' => 'Наименование', 'date' => 'Дата'])
    ->data([
        ['id' => 1, 'name' => 'Элемент 1', 'date' => '2023-01-01'],
        ['id' => 2, 'name' => 'Элемент 2', 'date' => '2023-02-01']
    ])
    ->hidden(['id']) // Скрываем поле ID
    ->sort('name');  // Сортировка по наименованию

// Настройка обработки клика по строке
$table->rowclick($form);

// Добавление новых строк
$table->append([
    ['id' => 3, 'name' => 'Элемент 3', 'date' => '2023-03-01']
]);

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

LTS(table).append(LTS(form).values());

Интеграция готовой верстки в проект

Что если клиент предоставляет готовую верстку с HTML, CSS и JavaScript? LOTIS ускоряет разработку и в этом случае, поскольку LOTIS обеспечивает позднее связывание событий и методов с объектами по их ID:

// Интегрируем HTML-код в проект
$mysite = LTS::Html('mysite.html')
// Подключаем внешний CSS
$mysite->CSS()->add('styles.css');
// Подключаем внешние скрипты
$mysite->JS()->add('scripts.js');
// Определяем события (функционал back-office)
$events = LTS::Events()
  ->client('clickbutton1', <<<JS alert(result); JS)
  ->server('clickbutton1', function ($args) { return 'Hello, mysite!'; });
// Привязывает событие к клику по кнопке с id=button1 из HTML-шаблона
$mysite->JS()->add(<<JS
        LTS(button1).listen('click', () => { LTS(events).clickbutton1(); });          
    JS);
// Собираем проект
$mysite->add($events);
LTS::Space()->build($mysite);

Адаптивная CSS Grid-вёрстка

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

// Создание сетки
$grid = LTS::Grid();

// Определяем устройство
$grid->deviceQuery('watch', '() => window.innerWidth <= 600 && window.innerHeight <= 600');

// Опрелеление режима dashboard
$grid->setMode('dashboard')
     ->device('desktop')
        ->areas(["header header",
            "menu content",
            "bar bar"])
        ->rows("60px 1fr auto")
        ->columns("200px 1fr")
     ->device('mobile')
        ->areas(["header", "content", "bar"])
        ->rows("60px 1fr auto")
        ->columns("1fr")
     ->device('watch')
        ->areas(["header", "content"])
        ->rows("50px 1fr")
        ->columns("1fr");
Переключаем сетку в клиентском приложении по кнопке:
$btnDashboard = LTS::Button()
    ->capt('? Панель')
    ->click(<<<JS
    LTS(grid).mode('dashboard')
JS);

Встроенная ORM

LOTIS позволяет использовать парадигму ООП при работе с MySql таблицами. Это повышает читаемость кода и обеспечивает гибкость в работе с базой данных.

// Подключение к базе:
$db = LTS::MySql('mydb', 'localhost', 'user', 'pass');

// Определение таблицы:
$users = $db->table('users');
$users->string('name', 100);
$users->string('email', 255);
$users->enum('status', ['active' => 'Активен', 'blocked' => 'Заблокирован']);
$users->table('role_id', $roles);  // внешний ключ
$users->create();  // создать в БД

// Вставка:
$users->value('name', 'Иван')
    ->value('email', 'ivan@test.com')
    ->insert();

// Обновление:
$users->value('status', 'blocked')->set(5);  // по ID=5

// Массовое обновление:
$users->value('status', 'active')->setall(['role_id' => 1]);

// Выборка:
$list = $users->all(['status' => 'active', 'ORDER' => '-created_at', 'LIMIT' => 10]);

// Сложная выборка через QueryBuilder:
$result = $users->query()
    ->where('status', 'active')
    ->where('name', '$иван')  // LIKE '%иван%'
    ->leftJoin($roles, 'users.role_id = roles.id', 'roles')
    ->orderBy('-created_at')
    ->limit(10)
    ->all();

DataView – документ с несколькими табличными частями

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

Разговоры о том, чтобы в WEB появилась логика работы с документами, похожая на 1С, велись еще с начала 2000-х. В версии 1С:Предприятие 8.2, был реализован механизм управляемого приложения, отвечающий на этот запрос. Но до сих пор все, что связано с 1С, является далеко не классическим WEB, требующим больших вычислительных ресурсов. Поэтому, создать сущность, позволяющую работать с документами в логике 1С, было вполне логичным и нужным решением.

Другие классы

В распоряжении программиста, использующего LOTIS, имеется около сорока классов. Это позволяет строить WEB-приложения различной сложности.

DataView.php — Главная форма: единый интерфейс для работы с документами
DataTable.php — Таблицы с сортировкой и отбором
FilterForm.php — Форма фильтрации таблиц
Stock.php — Централизованный учёт
Space.php — Сборка UI
Events.php — События через AJAX
Form.php — Форма ввода: базовый контейнер для полей
Input.php — Поле ввода текста
LookupField.php — Поле поиска с выпадающим списком
JS.php — Генерация JavaScript-логики на стороне PHP
CSS.php — Вставка и управление CSS-правилами на лету
Div.php — Универсальный контейнер
Vars.php — Система глобальных переменных
Grid.php — Сеточная вёрстка
Dialog.php — Модальное окно
MySql.php — Подключение к MySQL
MySqlField.php — Представление поля таблицы
MySqlTable.php — Работа с таблицей
QueryBuilder.php — Построитель SQL-запросов
MultiTable.php — Привязка подчиненных таблиц к главной
Button.php — Кнопка с действиями
Cells.php — Сетка элементов
Columns.php — Гибкая колоночная вёрстка
Accordion.php — Раскрывающиеся блоки
Construct.php — Первый базовый класс
DataSync.php — Синхронизация данных
Debug.php — Инструменты отладки
Element.php — Базовый класс всех UI-элементов
Ether.php — Базовый интерфейс
Html.php — Работа с HTML-тегами
Lang.php — Поддержка мультиязычности
LayerSlider.php — Переключение слоёв интерфейса
Logger.php — Логирование действий и ошибок
ProgressBar.php — Визуальный прогресс
Quark.php — Мини-реализация объектной модели
SimpleChart.php — Простые графики
Span.php — Inline-контейнер
Tabs.php — Вкладки
Video.php — Встраивание видео

? Расширение фреймворка

Архитектура LOTIS позволяет расширять его функциональность пользовательскими классами. Это дает возможность разрабатывать собственные компоненты и использовать их в своих проектах.

Пример:

class Option extends LTS\Element
{
    public function __construct($id = '')
    {
        parent::__construct($id);
        $this->tag('option');
    }

    public function inic($val, $caption)
    {
        $this->attr('value', $val)
            ->capt($caption);
        return $this;
    }
}

class Select extends LTS\Element
{
    public function __construct($id = '')
    {
        parent::__construct($id);
        $this->tag('select');
    }

    public function option($val, $caption = null)
    {
        $option = new Option();
        $option->inic($val, $caption ?? $val);
        $this->add($val, $option);
        return $this;
    }
}

Кстати о Tailwind...

Поскольку любой объект LOTIS имеет встроенные методы addclass и removeclass, позволяющие устанавливать список CSS-классов непосредственно для конкретного объекта, то создание специализированного конструктора Tailwind так и просится к реализации. А пока используем методы "в лоб": 

$card = LTS::Div()
    ->addclass('max-w-sm rounded overflow-hidden shadow-lg bg-white')
    ->addclass('transition duration-300 hover:shadow-xl');

?️ Что дальше?

LOTIS активно развивается, и в настоящее время Питерское издательство "Наука" готовит к публикации книгу по его применению в разработке WEB-приложений для бизнеса.

Следующие шаги:

  • Порт на Node.js для создания PWA

  • Интеграция с локальными базами данных

  • Поддержка TypeScript для статической проверки

  • Разработка системы тестов

  • Создание конфигуратора для визуальной разработки

Проектируя LOTIS, я хотел не просто упростить разработку на PHP, я искал новый уровень абстракции: не строить HTML, а создавать объектную модель бизнес-процессов. Чтобы эта модель стала живым интерфейсом - об этом заботится не программист, а фреймворк.

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

include_once 'newlotis/lotis.php';
$div = LTS::Div()->capt("Hello from LOTIS!");
LTS::Space()->build($div);

Комментарии (10)


  1. x89377
    20.04.2026 02:54

    Есть ссылка на пример ?


    1. O-Planet Автор
      20.04.2026 02:54

      Готовлю к публикации приложение для производственного учета на предприятии.


  1. samako
    20.04.2026 02:54

    Очень интересно. Лет 20-ть назад такое уже было, но сообщество отказалось от этого пути. Я и сам таким баловался по-молодости. Так что это, увы, не новая парадигма..

    Как проекта для своего фриланса - это нормально, но для большой компании вряд ли подойдёт - по целому ряду причин.


  1. init0
    20.04.2026 02:54

    Фреймворк для быстрой разработки сложных бизнес-приложений

    Я полагаю, что ваше представление о сложной бизнес-логике кардинально отличается от того, что принято таковой считать в отрасли.


    1. O-Planet Автор
      20.04.2026 02:54

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


      1. init0
        20.04.2026 02:54

        Начать и закончить можно прям с этого:

        Полное отсутствие доменного слоя, вся ваша бизнес логика это анонимные замыкания прямо внутри UI контроллеров. DataView одновременно и ui компонент, и контроллер, и репозиторий.

        А так, у вас просто нет даже базовой инфраструктуры для этого:

        - нет Composer (как минимум для автозагрузки по psr-4)

        - нет router

        - нет DI

        - нет REST API

        - сессии у вас нативные - как будем горизонтально масштабироваться?

        - с БД прям беда - нет полноценной ORM, запросы не подготовлены(!), нет миграций, мускуль прибит гвоздями, нет транзакций - в LTS\Stock::update гоним запросы через foreach (другой важный вопрос - почему не одним запросом) и молимся тихонечко, чтоб ничего не упало посередине

        - нет кэширования

        - нет CSRF, нет санитизации входных данных

        - нет даже базовых юнит тестов

        Это прям по верхам... Это не фреймворк в общепринятом понимании, а что-то типа RAD для прототипирования crud интерфейсов.


        1. O-Planet Автор
          20.04.2026 02:54

          Ключевое "в общепринятом понимании". А почему оно общепринято? Технология ради какой-то идеи? Я придерживаюсь другого правила: автоматизация нужна ровно настолько, чтобы приносить прибыль компании. Все сверх этого - попытка сохранить старый холодильник на балконе: вдруг пригодится! Удивительно, но в крутой западной корпорации зачастую можно встретить еще систему учета на FoxPro, которая работает и всех устраивает. Но российскому предпринимателю, продающему пирожки в переходе, конечно же нужно 1С:ERP! На всякий случай, вдруг пригодится!

          Теперь по поводу критики. Она имеет место быть, потому что Вы сейчас говорите об Enterprise-приложениях. Давайте тогда уж критиковать автомобили: они же не летают! Обратите внимание, как я позиционирую LOTIS:

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

          В LOTIS нет отдельного доменного слоя в классическом понимании DDD. Но это осознанный выбор, а не недостаток. Для большинства бизнес-приложений, которые заказывают (учет товаров, производственный, складской учет, планирование закупок и продаж, работа с клиентами, система документооборота, отчеты), доменная логика тесно связана с UI. В таких случаях разделение на слои часто приводит к избыточной сложности. В LOTIS вы можете создать отдельный доменный слой при необходимости — фреймворк не мешает этому. Но он не навязывает сложную структуру там, где она не нужна.

          Про composer я писал. Это тоже осознанный выбор: как можно меньше зависимостей. LOTIS использует spl_autoload_register для автоматической загрузки классов. Это упрощает подключение — достаточно одного файла lotis.php. Для проектов, где нужна автозагрузка по PSR-4, интеграция с Composer возможна, но не обязательна.

          Про модель MVC. И об этом я тоже писал! Отказ от этой модели - опять же, сознательный выбор. А почему, собственно, MVC - некий эталон? Вы же сами упомянули парочку других архитектур, микросервисная, к примеру. Можно вспомнить событийную - здравствуй Qt!. Давайте и его критиковать за то, что он не поддерживает MVC. Я предлагаю отказаться от MVC в WEB разработке, потому что многослойно и далеко не наглядно. Вместо этого предлагаю модель CMA и наглядность десктопного приложения.

          Router и REST API... Опять технология ради технологии. Зачем? LOTIS фокусируется на полном приложении, а не на API-first подходе. Для проектов, где нужен REST API, есть другие фреймворки. LOTIS решает задачу построения целостного приложения без разбивки на микросервисы. Почему, например, не требовать с таким же успехом обеспечивать REST API для Windows Form приложения?

          То же относится и к масштабированию. Для подавляющего большинства проектов, на которые ориентирован LOTIS, это не проблема. Если масштабирование необходимо, можно использовать кастомные обработчики сессий.

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

          Есть ли куда стремиться? Конечно. И с Вашим опытом критического взглада на то, как должно быть, думаю, LOTIS только бы выиграл. Другое дело, что большинство критиков почему-то не любят ничего создавать и не хотят замечать потенциал там, где он есть. И это проблема. Давайте так, любой мидл за пару вечером с помощью LOTIS может создать систему учета по типу WMS или CRM с учетом персональных требований заказчика. Назовите еще какие-то инструменты разработки с таким же быстрым входом, позволяющие это делать.


          1. Rsa97
            20.04.2026 02:54

            Удивительно, но в крутой западной корпорации зачастую можно встретить еще систему учета на FoxPro, которая работает и всех устраивает. Но российскому предпринимателю, продающему пирожки в переходе, конечно же нужно 1С:ERP! На всякий случай, вдруг пригодится!

            Тут всё очень просто. Если в вашей стране за последние 30 лет законы не менялись, то вы вполне можете сидеть на 30-летнем коде FoxPro. А вот если у вас законы и требования к бухучёту меняются по пять раз за год, самим допиливать свою FoxPro становится гораздо дороже, чем перейти на 1С с централизованным обновлением.

            Кстати, а сайт o-planet не на вашем Lotis’е написан? а то какой-то он кривоватый.


  1. fishan
    20.04.2026 02:54

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


    1. init0
      20.04.2026 02:54

      Такой топорный rage bait, что аж обидно