В этой статье я поделюсь своим дзеном в области бэкенда с начинающими инженерами-программистами. Это может быть полезно например для милых дам, или для детей 12+, которые прочитали учебники, но таки не осилили стандартные фреймворки и архитектуры, например MVC и REST (и ещё статья). Так же нельзя забывать об инвалидах и больных людях, у которых нет лишних сил для сложности. Я хочу избавить этих людей от страдания, нет причин для меланхолии.

Однако некоторые суровые программисты могут не понять что такое Дзен и кому нужна Простота 12+. Эта статья не для них. Это другая парадигма и разрыв шаблона.

Программирование может быть очень простым, если вы умеете писать код самостоятельно, и если вы 3-5 лет усердно грызёте гранит. Освоить мой Web API возможно за один день как алфавит, но практиковаться в написании «произведений» надо несколько лет. На самом деле я ничего не добавил, я просто расчистил «авгиевы конюшни» и выделил ядро веб-программирования, и назвал вещи своими именами.

Дисциплина — это не ограничение свободы
Это отсечение всего лишнего


Есть работающий пример этой технологии — самая простая в мире CMS ВебИздат.

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

Только со смертью догмы начинается наука


нельзя просто так взять и освоить бэкенд!

Фундаментальные понятия


KISS

Каждый просветлённый разработчик знает принцип KISS, и понимает для чего людям нужны простые инструменты для нелегкой работы, например язык PHP. Это хороший язык, но его надо содержать в простоте, и не усложнять. Необходимо выделить минимальное полезное-необходимое ядро-подмножество этого языка.

image

«Нанофреймворк» это ядро (хардкор) программирования — учить надо меньше, а не больше. Уровень сложности меньше примерно в сто раз, в сравнении с обычными фреймворками. Всё что сложнее 12+ мне не интересно, моя задача — обучение детей, используя простое подмножество языков. Это прожиточный минимум программиста. Супер строгий режим. Дзен и Кунг-фу. Веб-ассемблер.

структура профессии инженера-программиста: 1) психология труда и восприятия: научные исследования, дизайн информации, дизайн взаимодействия. 2) клиент-серверное веб-приложение: клиент (html, css, js), сервер (php). 3) оформление: графический дизайн, озвучка, рельеф

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

Нормальные программисты делятся на два типа:

  1. инженеры-изобретатели (1%) — те кто способны написать фреймворк(шаблон) для себя или для других
  2. слесари-монтажники и верстальщики (99%) — те кто работают и изобретают в рамках готового шаблона

Оба типа нужны стране, направление зависит от способностей и талантов.

Нанофреймворк PHP10


Я суровый программист — «тонкий» сервер использую как «БД на файлах» для мобильного «толстого» клиента. PHP я выбрал потому что он везде, и местами даже бесплатно. PHP прекрасен тем что он хорошо сочетается с HTML и JS, и выглядит как их логичное продолжение на сервере. Основные веб-языки это квартет — JS+CSS+HTML+PHP.

Сервер может быть очень простым — всего около десятка микроскопических функций, которые возможно освоить за один день:

  1. запросить логин и пароль
  2. создать папку
  3. удалить папку
  4. переименовать-переместить папку
  5. сканировать папку
  6. создать файл
  7. загрузить файл
  8. сохранить файл
  9. прочитать файл
  10. удалить файл

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

инженер-изобретатель обращается к коллективному разуму, и говорит: Тостер, давай еще!

Мне нужны только простые стандартные серверные функции, которые я использую дистанционно из браузера. Этих достаточно для создания CMS, и этого достаточно для начинающих. Простота сервера — это максимальная скорость его работы, ведь нормальный php-процесс «рождается чтобы поскорее умереть» (кроме ненормального случая использования SSE).

Архитектура простейшего веб-приложения


сайт

мобильное приложение с сервером

Комбинируя относительные и абсолютные пути в html и php файлах можно построить необходимую структуру файлов, например чтобы созданный контент мог работать без сервера. То есть например — сначала вы создаете контент на клиенте используя сервер, а после используете готовый контент например в виде phonegap-приложения для работы на клиенте.

мобильное приложение без сервера

Web API


Клиент может получать от Сервера программы-страницы или данные, и может отправлять на Сервер данные. Окна Клиента могут обмениваться данными между собой. API сервера достаточно надежно защищено базовой авторизацией. Вы можете добавить свои функции к базовым функциям PHP10.

web api : виды обмена данными

JSONET


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

обмен данными в коллективном разуме jsonet

<Брюс Ли сказал: простота это высшая ступень искусства

Для работы необходим файл .htaccess
AddDefaultCharset UTF-8

DirectoryIndex index.php index.html 

RemoveHandler .html .htm
AddType application/x-httpd-php .php .html 

<Files .htaccess>
order allow,deny
deny from all
</Files>

ErrorDocument 404 /404.html

404.html — это файл страницы ошибки, лежащий в корне сервера

Первый запуск сервера — авторизация Владельца, создание файлов защищенных авторизацией
<?php   
if(empty($_SERVER['PHP_AUTH_USER']))           //если браузер еще не передал серверу логин и пароль 
	{	
	header('WWW-Authenticate: Basic realm="WWW-Authenticate"');    
	header ('HTTP/1.0 401 Unauthorized'); 
	exit();                                                
	}
//если клиент авторизовался:

//зашифровать логин и пароль
$login = md5($_SERVER['PHP_AUTH_USER']);                     
$parol = md5($_SERVER['PHP_AUTH_PW']);

$html_1 = file_get_contents('./шаблон.html');   //шаблон документа

//содержимое html-файла который надо создать при первом запуске:
$html_2 = <<<_END
<?php   
//внедрение авторизации - встраивание зашифрованных логина и пароля:
if (md5(\$_SERVER['PHP_AUTH_USER']) != '$login' || md5(\$_SERVER['PHP_AUTH_PW']) != '$parol')
	{
	header('WWW-Authenticate: Basic realm="WWW-Authenticate"');
	header ('HTTP/1.0 401 Unauthorized'); 
	exit(); 
	}
?>
$html_1    //встраивание шаблона
_END;

file_put_contents('файл.html', $html_2);  //создание html-файла
?>

//программа передаваемая клиенту после ввода логина и пароля:
<!DOCTYPE HTML><html><head><meta charset="utf-8" /><meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height" />
<script type="text/javascript">
window.onload = function(){window.location = 'файл.html'}  //переход к созданному файлу
</script></head><body></body></html>


Создание домена или файла
js-функция:

var php_создать_домен_документ = function(имя, путь)
{ 
var x = JSON.stringify([имя, путь]);
var запрос = new XMLHttpRequest();
запрос.open('POST', 'создать_домен_документ.php');   
запрос.send(x);  
}

файл создать_домен_документ.php:

<?php     
//тут может быть запрос авторизации

$x = json_decode(file_get_contents('php://input'));  //распаковка полученного JSON
// $x[0] — имя
// $x[1] — путь

mkdir('./' . $x[1] . '/' . $x[0]);      //создать папку 

$содержимое_документа = file_get_contents('./шаблон.html');

//создать документ
file_put_contents('./' . $x[1] . '/' . $x[0] . '/index.html', $содержимое_документа);
?>


Удаление домена
js-функция:

var php_удалить_домен = function(путь)
{ 
var x = JSON.stringify([путь]);
var запрос = new XMLHttpRequest();
запрос.open('POST', 'удалить_домен.php');   
запрос.send(x);  
}

файл удалить_домен.php:

<?php      
//тут может быть запрос авторизации

$x = file_get_contents('php://input');
  	
function rrmdir($dir)   //функция для удаления папки и всего её содержимого
{
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);}}
reset($objects);
rmdir($dir);}
};

rrmdir('./' . $x[0]);
?>


Удаление файла
js-функция:

var php_удалить_файл = function(путь)
{ 
var x = JSON.stringify([путь]);
var запрос = new XMLHttpRequest();
запрос.open('POST', 'удалить_файл.php');   
запрос.send(x);  
}

файл удалить_файл.php:

<?php      
//тут может быть запрос авторизации

$x = file_get_contents('php://input');

unlink('./' . $x[0]);
?>


Переименование или перемещение домена
js-функция:

var php_переименовать_домен = function(старый_путь, новый_путь)
{ 
var x = JSON.stringify([старый_путь, новый_путь]);
var запрос = new XMLHttpRequest();
запрос.open('POST', 'переименовать_домен.php');   
запрос.send(x);  
}

файл переименовать_домен.php:

<?php      
//тут может быть запрос авторизации

$x = json_decode(file_get_contents('php://input'));
  
rename('./' . $x[0], './' . $x[1]);
?>


Сканирование домена
js-функция:
var php_сканировать_домен = function(путь)
	{   
		var x = JSON.stringify([путь])
		var запрос = new XMLHttpRequest()
		запрос.open('POST', 'сканировать_домен.php')
		запрос.send(x)

		запрос.onreadystatechange = function()  //функция обработки ответа сервера
			{
			    if(запрос.readyState === 4)
			        {
			        	отобразить_содержимое_домена(запрос.responseText)
			        }
			}
	}

var отобразить_содержимое_домена = function(ответ)
	{     
		var ответ = JSON.parse(ответ)

		for (var y=0; y< ответ.length; y++)
		    {  
		        if( ответ[y][0] !=='.' && ответ[y] !== 'index.html' )  //фильтрация лишнего
		            { 
		                //создание списка имен
		                var кнопка = document.createElement('span')
		                кнопка.id = 'кнопка_ссылка'
		                кнопка.className = 'кнопка_ссылка_раздел_неакт'
		                кнопка.textContent = ответ[y]
		                список_имен.appendChild(кнопка)
		            }
		    }
	}

файл сканировать_домен.php:

<?php  
//тут может быть запрос авторизации
    
$x = json_decode(file_get_contents('php://input'));

$массив = json_encode(scandir($x[0]));

print "$массив";
?>


Загрузка медиафайлов
файл загрузить_картинку.php:
<?php      
//тут может быть запрос авторизации

//проверка типа файла
if($_FILES['файл']['type'] == 'image/gif' || $_FILES['файл']['type'] == 'image/jpeg' || $_FILES['файл']['type'] == 'image/png' || $_FILES['файл']['type'] == 'image/svg+xml' )
	{
		$имя_файла = basename($_FILES['файл']['name']);  
		copy($_FILES['файл']['tmp_name'],  './' . $_POST['путь'] . $имя_файла);    

		echo "<script type='text/javascript'> parent.сканировать_домен() </script>";
	}
else
	{
		echo "<script type='text/javascript'> alert('неверный тип файла') </script>";
	};
?>

файл загрузить_аудио.php:

<?php      
//тут может быть запрос авторизации

//проверка типа файла
if($_FILES['файл']['type'] == 'audio/vnd.wave' || $_FILES['файл']['type'] == 'audio/mpeg' || $_FILES['файл']['type'] == 'audio/aac' )
	{
		$имя_файла = basename($_FILES['файл']['name']);  
		copy($_FILES['файл']['tmp_name'],  './' . $_POST['путь'] . $имя_файла);    

		echo "<script type='text/javascript'> parent.сканировать_домен() </script>";
	}
else
	{
		echo "<script type='text/javascript'> alert('неверный тип файла') </script>";
	};
?>

файл загрузить_видео.php:

<?php      
//тут может быть запрос авторизации

//проверка типа файла
if($_FILES['файл']['type'] == 'video/mp4' || $_FILES['файл']['type'] == 'video/mpeg' )
	{
		$имя_файла = basename($_FILES['файл']['name']);  
		copy($_FILES['файл']['tmp_name'],  './' . $_POST['путь'] . $имя_файла);    

		echo "<script type='text/javascript'> parent.сканировать_домен() </script>";
	}
else
	{
		echo "<script type='text/javascript'> alert('неверный тип файла') </script>";
	};
?>


Сохранение изменений файла
js-функция:
var php_сохранить_страницу = function(путь, автор, описание, заголовок, тело_документа)
{
var x = JSON.stringify([путь, автор, описание, заголовок, тело_документа]);
var запрос = new XMLHttpRequest();
запрос.open('POST', 'сохранить_страницу.php');   
запрос.send(x); 
}


файл сохранить_страницу.php:
<?php      
//тут может быть запрос авторизации

//[путь, автор, описание, заголовок, тело_главной_страницы]
$x = json_decode(file_get_contents('php://input'));

include './шаблон_страницы.html';

//сохранить документ
file_put_contents('./' . $x[0] . '/index.html', $содержимое_документа);
?>


файл шаблон_страницы.html:

<?php
$содержимое_документа = <<<_END
<!DOCTYPE HTML><html><head>
<meta name="author" content="$x[1]" />
<meta name="description" content="$x[2]" />
<title>$x[3]</title>
</head><body>$x[4]</body></html>
_END;
?>


Чтение файла
js-функция:
var php_прочитать_файл = function(путь)
  {
      var x = JSON.stringify([путь]);
        
      var запрос = new XMLHttpRequest();
      запрос.open('POST', 'редактор/сервер/прочитать_файл.php');   
      запрос.send(x); 

      запрос.onreadystatechange = function()
        {
          if(запрос.readyState === 4)
            {
              var ответ = запрос.responseText
              //или
              var ответ = JSON.parse(запрос.responseText)
            }
        }
  }
}


файл прочитать_файл.php:
<?php      
//тут может быть запрос авторизации

$x = json_decode(file_get_contents('php://input'));
$строка = file_get_contents('$x[0]);
print "$строка";
?>


Продолжение следует
Это первая версия нанофреймворка.
Электропочта на Яндексе для отзывов и предложений: max.minimus@


image
Поделиться с друзьями
-->

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


  1. vlreshet
    06.03.2017 10:11
    +18

    Ээээ… ээ… я один не понял что происходит?


    1. zenn
      06.03.2017 10:17

      Вы не один. Занимаюсь веб-ом далеко не первый год, но что, а главное зачем делает автор мне вовсе не ясно. Если основываться только на «животных» чувствах и инстинктах(которые присущи php-программистам в первый год жизни) то похоже что автор «изобрел» свой первый файловый менеджер через призму html/js и бэкенд php, вместе с чем стандартно принятые термины заменил на те, которые не понимает.


      1. vlreshet
        06.03.2017 10:34

        Не, ну то что он изобрёл что-то вроде подхода которым пользовались годах в девяностых (набросать кучу файлов — и сказать что это сайт) — я понял. Но при чём тут какое-то наноядро, PHP10 (O_o), какие-то диаграммки, и милых дам с детьми приплёл…


        1. zenn
          06.03.2017 10:41

          Да, пост явно не для хабра, меня тоже «притянуло» php10, но сразу же насторожили непонятные мемо-подобные картинки (ну не пишут так технари) и неадекватные блок-схемы (больше всего, простите, поржал с пикчи JSONET — автор наконец узнал о том, что из себя представляет классическая «сеть интернет», где пользователь может обмениваться данными с другими пользователями и серверами).


          1. Brom95
            06.03.2017 10:47
            +2

            А HTML10 не хотите?)))


          1. vlreshet
            06.03.2017 10:47
            +2

            Какая-такая сеть интернет? Это ж коллективный разум! :D

            тыц
            image


  1. BlackJet
    06.03.2017 10:21
    +4

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


    1. zenn
      06.03.2017 10:31
      +4

      Добавлю — она ОЧЕНЬ вредная и автор это узнает, когда «сие» творение увидит хоть 1 человек который хоть чуть-чуть может в безопасность (вообще, за такое нужно ломать ноги и руки):

      // удаление файла на сервере
      $x = file_get_contents('php://input'); // шедеврально! Зачем они там придумали свои $_POST/$_GET/$_FILE?!
      
      // ...[skip]... какой-то бесполезный цикл с анлинком всего в папке 
      
      rmdir('./' . $x[0]); // как думаете, что будет когда прийдет [0] = ../../../ ? :D 
      
      

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


      1. Brom95
        06.03.2017 10:41

        Рискну предположить, что в погоне за минимализмом и «Нанофреймворком» ( а более минималистичные создадут потом пико!) автор мог понадеяться на то, что будет потом обертка поверх этого решения.


        1. zenn
          06.03.2017 10:45

          Да вы оптимист! Глядишь, обертку свою с блекджеком и ******* напишет на Сях для rmdir() и unlink() или вообще запретят в бинарный буфер совать всякие там подозрительные символы (ирония)


          1. Brom95
            06.03.2017 10:48

            можно же сразу в 16-ти ричных кодах, чтоб минималистичнее!))


      1. SerafimArts
        06.03.2017 14:29

        Ну… $_POST/$_GET/etc не работает от слова "вообще", допустим, в случае выполнения такого запроса: PUT /resource + Content-Type: multipart/form-data, а чтение из стрима stdin ничего так, что-то, да отдаёт...


  1. Brom95
    06.03.2017 10:34
    +1

    Простите, а БД на файлах, это не прошлый век?


  1. vlreshet
    06.03.2017 10:44

    Сделайте мне развидеть это
    var отобразить_содержимое_домена = function(ответ)
    	{     
    		var ответ = JSON.parse(ответ)
    
    		for (var y=0; y< ответ.length; y++)
    		    {  
    		        if( ответ[y][0] !=='.' && ответ[y] !== 'index.html' )  //фильтрация лишнего
    		            { 
    		                //создание списка имен
    		                var кнопка = document.createElement('span')
    		                кнопка.id = 'кнопка_ссылка'
    		                кнопка.className = 'кнопка_ссылка_раздел_неакт'
    		                кнопка.textContent = ответ[y]
    		                список_имен.appendChild(кнопка)
    		            }
    		    }
    	}
    
    
    файл сканировать_домен.php:
    <?php  
    //тут может быть запрос авторизации
        
    $x = json_decode(file_get_contents('php://input'));
    
    $массив = json_encode(scandir($x[0]));
    
    print "$массив";
    ?>
    


    1. smple
      06.03.2017 13:21
      +4

      скоро закончат и 1с разработчики переедут на php10


    1. bioroot
      06.03.2017 20:11

      Это просто современная интерпретация боярского диалекта.


  1. ellrion
    06.03.2017 10:48
    +3

    Простите, но почему то ощущение, что я посмотрел не статью о php, а некий вариант Манускрипта Войнича.


  1. uLow
    06.03.2017 12:43
    +7

    Я хочу избавить этих людей от страдания

    Я даже представить боюсь, что было бы, если бы автор намерянно хотел причинить те самые страдания…

    И ведь самое забавное — автор старался, тратил время, усилия, чтобы выпустить это «нечто». Ждём продолжения киллер-фреймворка на 1 апреля?


    1. vlreshet
      06.03.2017 13:36
      +4

      Я прям вижу рекламу на баннерах сомнительной рекламы: фотография с испуганным разработчиком и подпись «Разработчики Laravel потеряли дар речи, когда увидели ЭТО. Теперь для создания сайта надо всего лишь… Читать далее»


      1. iit
        06.03.2017 14:55

        Я тот самый разраб с laravel, после этой статьи и еще вот этой https://habrahabr.ru/post/321982, я заработал сотрясение мозга от фейспалмов.


  1. ZonD80
    06.03.2017 16:42
    -3

    Котята, а я улыбаюсь и почесываю бороду. Why not?)


  1. Rastishka
    06.03.2017 18:11
    +4

    Нормальные программисты делятся на два типа:
    инженеры-изобретатели (1%) — те кто способны написать шаблон для себя или для других
    слесари-монтажники и верстальщики (99%) — те кто работают в рамках готового фреймворка
    Автор причисляет себя конечно же к первым? =)
    Давно замечал что у всяких фриков как правило ЧСВ заклинило.


    1. SerafimArts
      06.03.2017 19:06
      +2

      Ну, к слову сказать, конечно не в таком соотношении, я бы сказал 2 к 8 (20% vs 80%) но в целом — это так… =\


      … Правда ещё есть третья группа, которая лезет учить других не изучив основы, и основываясь на опыте 10-ти летней давности. Который в современном строе не столько ненужен, сколько вреден. =)


  1. DevMan
    06.03.2017 19:14

    Продолжение следует
    rly? может не стоит?

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


  1. akubintsev
    06.03.2017 22:31
    +2

    Главное всё оформить с шутками-прибаутками. Олдскульный академизм уже не в моде =)) Авось за умного прокатит.


  1. dom1n1k
    09.03.2017 18:47

    Опять этот графоман