Создание и использование вспомогательного метода

2.2 Содержание базы данных MySQL

Разрабатываемый мною сайт, для хранения информации будет использовать базу данных со следующей структурой:

  • Project
  • Work_experience
  • Education
  • Tech_skill
  • Soft_skill

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

Таблица project состоит из 4 полей: id_project – идентификатор, number – порядковый номер, url – ссылка на проект, type – используемый код в проекте.

Таблица work_experience состоит из 4 полей: id_work – идентификатор, name – название места работы, time – период работы, duties – исполняемые обязанности.

Таблица education состоит из 4 полей: id_education – идентификатор, name – название учебного заведения, department – профиль образования, year – период обучения.

Таблица tech_skill состоит из 2 полей: id_tech_skill – идентификатор, name – название навыка.

Таблица soft_skill состоит из 2 полей: id_soft_skill – идентификатор, name – название навыка.

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

Параметры POST

В настоящее время предпочтительным методом отправки данных формы является POST (особенно при случаях, в которых осуществление действий приводит к постоянным изменениям, таких как ввод информации в базу данных). Набор данных формы включается в тело формы при перенаправлении формы к обрабатывающему агенту (в данном случае к интерпретатору PHP). Строка URL не претерпевает каких-либо видимых изменений, отражающих разнообразие передаваемых данных.

Среди разработчиков распространена ничем не оправданная уверенность в том, что метод POST более безопасен, чем GET. В действительности ни один из этих методов не является более или менее безопасным, чем другой. Посетитель может столь же успешно просматривать переменные и данные, отправляемые с помощью метода POST, как и с помощью метода GET. Единственное различие состоит в том, что в первом случае передаваемые данные не обнаруживаются в адресной строке. Но это не означает, что они скрыты. Данные, отправленные с помощью метода POST, могут просматриваться и модифицироваться пользователем веб-сайта.

Первым и наиболее важным правилом программирования, особенно программирования для сети, является следующее:

Никогда не доверять входным данным.

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

Данные передаваемой формы становятся в большей или меньшей степени безопасными, только если запрос защищен с использованием SSL, TLS или какого-то другого способа шифрования. Но к конечному пользователю или посетителю данные все равно поступают в открытом виде, поэтому для него так или иначе остается возможность просматривать и изменять данные. Дело в том, что с помощью протокола SSL осуществляется просто шифрование данных, передаваемых по сети, что не позволяет рассматривать данные в открытом виде на этапе их прохождения от отправителя к получателю. Что же касается возможности для посетителя вносить изменения в данные формы, то в протоколе SSL для предотвращения этого ничего не предусмотрено.

Чтобы изменить способ передачи данных в предыдущем примере, нужно внести следующие изменения:

Исходная HTML-разметка документа

Страница-обработчик sports.php

Регистрация виджетов

Чтобы виджеты отобразились на страницах сайта, необходимо зарегистрировать из функцией в файле functions.php. В аргументах функции я так же добавил немного разметки Bootstrap , которая будет добавлена в каждый блок с виджетом.

if (function_exists('register_sidebar'))
register_sidebar(array(
	'before_widget' => '<div class="card my-4 widget">',
	'after_widget'  => '</div></div>',
	'before_title'  => '<h5 class="card-header">',
	'after_title'   => '</h5><div class="card-body">',
));

Ну и теперь в разделе Внешний вид → Виджеты вы можете добавлять в сайдбар нужные вам виджеты путём перетаскивания. Более подробно о создании и добавлении виджетов в WordPress можно прочитать в этой статье.

Шаблоны в PHP для чайников

И снова здравствуйте. Давно я как-то не писал ничего
путного, даже как-то самому неприятно. Так что сразу к теме. Давайте,
товарищи умники, забудем такие слова, как XML, XHTML и прочий X…, и
поговорим о вещах, приближенных к реальности.

Сужествует такая «проблема», как разделение оформления и
содержания, и отделение исполняемого кода от получаемого html’я. Мухи —
там, котлеты — тут. Грубо говоря, программист программирует, дизайнер
дизайнит и никто никому не мешает жить. А если надо поменять что-то в
оформлении, то сделать это сможет один оформитель, сиречь дизайнер,
самостоятельно.

PHP хорош (хорош, собака!) тем, что позволяет встраивать
исполняемые конструкции прямо в html. Плюсы понятны. Минусы, например:
довольно сложно менять оформление в таком коде: echo
«<b>».$boldtext.»</b>»; Глупый дизайнер испугается и убежит, а
умный программист скажет «я вам не глупый дизайнер, чтобы ерундой
заниматься».

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

То есть, что-то вроде такого:

<html>

<title></title>

<body>

</body>

<html>

Там, где стоит , движок выводит заголовок, там,
где — соответственно, текст.

Легко и просто. И все счастливы. И это правильно. Но! Тут
и начинается маразм. Сначала пишется «движок шаблонов», что-то (я утрирую)
вроде такого:

$page = str_replace
(«», $title, $page);

$page = str_replace
(«», $text, $page);

Дальше — больше. Оказывается, что в некоторых случаях
этого мало. Нужно больше функций! Например, нам нужно проверять: если
пустой, то выводить одно, если не пустой, то выводить другое, то
есть, фактически, вводить уже минимальную логику отображения. И мы пишем
супер-пупер наророченый язык шаблонов. На PHP. И называем его SMARTASS
(Super Mega And Revolutionary Totally Automatized Shablon System).

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

А теперь потрясем мозгами и хорошенько подумаем, что же у
нас получилось. У нас получился фактически язык программирования,
написанный на PHP, который можно встраивать в html-код и тем самым менять
логику его (html-кода) отображения.

Поздравим друг друга. У нас получился PHP, написанный на
PHP. Велосипед для велосипеда. Осмысление этого придет позже.

А теперь возвращаемся к первому примеру.

<html>

<title></title>

<body>

</body>

<html>

Помните? Сравним его со следующим примером и попробуем
найти кардинальные различия.

<html>

<title><?=$title?></title>

<body>

<?=$text?>

</body>

<html>

Чем он кардинально отличается? Ни чем. Глупый верстальщик
поймет, если ему сказать «нужно вставить переменную text — пиши
<?=$text?>». Вместе с тем, это — не что иное, как сокращенная запись
оператора echo. И никакого интерпретатора шаблонов не нужно.

То есть следующий пример php-страницы выведет все, как
надо:

<?php

$text = «Это текст»;

$title = «Это заголовок»;

?>

<html>

<title><?=$title?></title>

<body>

<?=$text?>

</body>

<html>

Дальше — больше. Выносим все шаблоны в отдельный файл. И
пишем просто:

<?php

$text = «Это текст»;

$title = «Это заголовок»;

include «template.html»;

?>

Идея понятна? В процессе исполнения php-скрипта нужные
части выкладываем в переменные. Потом — инклюдим html-файл, где в нужных
местах проставлено .

Верстальщику же, чтобы научиться работать с такими
«шаблонами», нужно всего 3–5 минут для ознакомления с основами синтаксиса
PHP. И не надо учить какой-то навороченный язык шаблонов, который ему
больше никогда не пригодится.

Ну что плохого в таком вот шаблоне страницы?

<html><title><?=strtoupper($title)?></title>

<body>

<? if ($text==»»): ?>

Текста нет, пусто.

<? else: ?>

Введеный текст:
<b><?=$text;?></b>

<? endif; ?>

</body>

</html>

Плюсы — налицо. Для его вывода не нужно никаких
дополнительных вещей. Кроме PHP.

Вот, собственно, и все.

PS. Уважаемые умники. Данный способ «шаблонизации»
действительно покрывает 95% нужд простых смертных. Если вам что-то не
нравится — идите, побрейтесь бритвой Оккама.

  Обсудить эту статью на форуме

Книги для обучения

Скажу сказу, я не фанат книг. Когда речь идет о интернет-технологиях. Это все равно что объяснять человеку из племени Масаи что такое wi-fi. Никакие рисунки не помогут нормально все понять. И тем не мене, я хочу предоставить вам небольшой список книг по php для чайников, которые котируются среди профессионалов.

Мне бы хотелось, чтобы вы действительно добились цели и если вам кажется, что этот вариант обучения подойдет вам лучше – я с удовольствием предоставлю информацию.

PHP и MySQL. Разработка Web-приложений– отличная книга которая подойдет новичку. Первым делом автор покажет как настроить Apache (HTTP-сервер), PHP и MySQL (база данных), затем подскажет, как выбрать редактор кода. В книге рассматривается: синтаксис языка, самые полезные функции, создание собственного движка и ряда других функций.

В общем, ничего удивительного не правда ли? Но тем не менее это настоящий учебник с уникальной информацией, которую вы больше нигде не найдете. Это уже пятое издание, то есть никаких устаревших сведений не будет. Книга выпущена в 2015 году.  Для того, чтобы начинать самому знакомиться с кодом – самое оно.

HTML, JavaScript, PHP и MySQL. Джентльменский набор Web-мастера – Это более детальный учебник по изучению php. В нем затрагиваются несколько других полезных языков программирования, без которых полноценное создание веб приложений невозможно.

Читается достаточно легко, подходит для самостоятельного изучения и обучения студентов. Автор затрагивает такие темы как: основы php, динамическое формирования страницы при помощи CSS (каскадная таблица стилей), администрирование баз данных, создания динамических страниц при помощи JavaScript.

Создаем динамические веб-сайты с помощью PHP, MySQL, JavaScript, CSS и HTML5 – данную книгу я бы посоветовал более продвинутым читателям, которые уже обладают основными навыками HTML верстки. Если вы когда-либо изучали это, и еще помнете основные принципы тогда эта книга для вас.

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

PHP и MySQL. От новичка к профессионалу – и завершает наш обзор книга Кевина Янка, в ней автор делает сильный уклон на создание веб-приложений с базой данных.

Книга очень легкая, отлично подойдет для самостоятельного обучения.

Проблемы дизайна в контексте

Важным аспектом шаблонов проектирования является выявление и документирование ключевых идей, которые отличает хорошую систему от плохой системы (это может быть дом, компьютерная программа или объект повседневного использования), а также помощь в проектировании будущего. системы. Идея, выраженная в шаблоне, должна быть достаточно общей, чтобы ее можно было применять в самых разных системах в ее контексте, но все же достаточно конкретной, чтобы дать конструктивное руководство.

Диапазон ситуаций, в которых применяются проблемы и решения, рассматриваемые в шаблоне, называется его контекстом

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

Например, шаблон Александра «МЕСТО ЖДАТЬ» обращается к автобусным остановкам так же, как и к комнатам ожидания в хирургии, но при этом предлагает полезные и конструктивные решения. Книга « Шаблоны дизайна » «Банда четырех» автора Gamma et al. предлагает решения, не зависящие от языка программирования и прикладной области программы.

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

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

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

Баланс сил

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

Часто эти проблемы возникают из-за конфликта разных интересов или «сил». Образец возникает в виде диалога, который затем поможет уравновесить силы и, наконец, принять решение.

Например, может быть шаблон, предлагающий беспроводной телефон. Силами будет необходимость общаться и одновременно заниматься другими делами (приготовление пищи, осмотр книжной полки). Очень конкретным шаблоном будет просто «БЕСПРОВОДНОЙ ТЕЛЕФОН». Более общие шаблоны — «БЕСПРОВОДНОЕ УСТРОЙСТВО» или «ВТОРИЧНАЯ ДЕЯТЕЛЬНОСТЬ», предполагая, что второстепенная деятельность (например, разговор по телефону или осмотр карманов джинсов) не должна мешать другим действиям.

Несмотря на то, что в своем контексте это довольно неспецифично, силы в шаблоне «ВТОРИЧНАЯ ДЕЯТЕЛЬНОСТЬ» очень похожи на силы в «БЕСПРОВОДНОМ ТЕЛЕФОНЕ». Таким образом, конкурирующие силы можно рассматривать как часть сущности концепции дизайна, выраженной в шаблоне.

Паттерны содержат собственное обоснование

Обычно шаблон содержит обоснование, относящееся к некоторым заданным значениям

Для Кристофера Александра очень важно думать о людях, которые будут соприкасаться с архитектурой. Одна из его ключевых ценностей — заставлять этих людей чувствовать себя более живыми

Он говорит о «качестве без имени» (QWAN).

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

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

Сосредоточившись на влиянии на человеческую жизнь, мы можем выявить закономерности, не зависящие от меняющихся технологий, и, таким образом, найти «вневременное качество» (Александр).

Обзор вспомогательных функций

Если необходимо выполнить те же задачи на разных страницах сайта, можно использовать вспомогательное приложение. Веб-страницы ASP.NET включает несколько вспомогательных функций, и вы можете скачать и установить гораздо больше. (Список встроенных вспомогательных функций в веб-страницы ASP.NET приведен в кратком справочнике по API ASP.NET.) Если ни один из существующих вспомогательных функций не соответствует вашим потребностям, вы можете создать собственный модуль поддержки.

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

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

HTML шаблон

Bootstrap v4 начальный шаблон

Для его работы понадобятся файлы bootstrap.min.css и bootstrap.min.js, которые мы соответственно добавляем в папки css и js нашей темы. Скачать их можно по кнопке Download source code на той же странице.

Перед тем, как тема будет «разрезана» на шапку и футер вы можете добавить весь исходный код шаблона в файл index.php и увидеть, что тема работает. Путь до папки с темой указывается функцией — это чтобы сразу в теме указать ссылки для скриптов. Должно получится примерно следующее:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="/docs/4.0/assets/img/favicons/favicon.ico">

    <title>Starter Template for Bootstrap</title>

    <link rel="canonical" href="https://getbootstrap.com/docs/4.0/examples/starter-template/">

    <!-- Bootstrap core CSS -->
    <link href="<?=get_template_directory_uri();?>/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="<?=get_template_directory_uri();?>/css/starter-template.css" rel="stylesheet">
  </head>

  <body>

    <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
      <a class="navbar-brand" href="#">Navbar</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <div class="collapse navbar-collapse" id="navbarsExampleDefault">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item active">
            <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Link</a>
          </li>
          <li class="nav-item">
            <a class="nav-link disabled" href="#">Disabled</a>
          </li>
          <li class="nav-item dropdown">
            <a class="nav-link dropdown-toggle" href="http://example.com" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
            <div class="dropdown-menu" aria-labelledby="dropdown01">
              <a class="dropdown-item" href="#">Action</a>
              <a class="dropdown-item" href="#">Another action</a>
              <a class="dropdown-item" href="#">Something else here</a>
            </div>
          </li>
        </ul>
        <form class="form-inline my-2 my-lg-0">
          <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
          <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
        </form>
      </div>
    </nav>

    <main role="main" class="container">

      <div class="starter-template">
        <h1>Bootstrap starter template</h1>
        <p class="lead">Use this document as a way to quickly start any new project.<br> All you get is this text and a mostly barebones HTML document.</p>
      </div>

    </main><!-- /.container -->

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="<?=get_template_directory_uri();?>/js/vendor/jquery-slim.min.js"><\/script>')</script>
    <script src="<?=get_template_directory_uri();?>/js/vendor/popper.min.js"></script>
    <script src="<?=get_template_directory_uri();?>/js/bootstrap.min.js"></script>
  </body>
</html>

Если все сделано верно, то на главной странице сайта отобразится тема Bootstrap 4.

Возможные способы реализации

Есть много способов реализовать шаблонизатора для DOM под капотом — от самых простых до сложнейших. Рассмотрим два основных:

  1. Заменить по регулярному выражению все переменные, встречающиеся в шаблоне, на данные и с помощью innerHTML поместить получившуюся разметку в DOM.
  2. Написать полноценный интерпретатор шаблонов, который будет символ за символом читать шаблон, разбивать его на токены, строить синтаксическое дерево и по этому дереву собирать разметку.

Первый способ — базовый и немного «костыльный». Его опасность — в innerHTML, который нежелательно использовать в более-менее серьёзных приложениях. Второй способ — достаточно мощный: он позволяет вводить различные операторы и операции в шаблон, превращая шаблоны в язык программирования.

Сейчас мы осуществим первый способ реализации, чтобы обрести базовое понимание шаблонизации.

Класс

<?php
/**
 * Class wrapper for working with PDO
 */
class DB
{
  /**
   * Настройки подключения
   * Лучше выносить в конфиг
   * self::DB_HOST -> Config::DB_HOST
   */
  const DB_HOST = '127.0.0.1'; // localhost
  const DB_USER = 'root';
  const DB_PASSWORD = '';
  const DB_NAME = 'pdo';
  const CHARSET = 'utf8';
  const DB_PREFIX = '';

  /**
   * @var PDO
   */
  static private $db;

  /**
   * @var null
   */
  protected static $instance = null;

  /**
   * DB constructor.
   * @throws Exception
   */
  public function __construct(){
    if (self::$instance === null){
      try {
        self::$db = new PDO(
          'mysql:host='.self::DB_HOST.';dbname='.self::DB_NAME,
          self::DB_USER,
          self::DB_PASSWORD,
          $options = 
        );
      } catch (PDOException $e) {
          throw new Exception ($e->getMessage());
      }
    }
    return self::$instance;
  }

  /**
   * @param $stmt
   * @return PDOStatement
   */
  public static function query($stmt)  {
    return self::$db->query($stmt);
  }

  /**
   * @param $stmt
   * @return PDOStatement
   */
  public static function prepare($stmt)  {
    return self::$db->prepare($stmt);
  }

  /**
   * @param $query
   * @return int
   */
  static public function exec($query) {
    return self::$db->exec($query);
  }

  /**
   * @return string
   */
  static public function lastInsertId() {
    return self::$db->lastInsertId();
  }

  /**
   * @param $query
   * @param array $args
   * @return PDOStatement
   * @throws Exception
   */
  public static function run($query, $args = [])  {
    try{
      if (!$args) {
        return self::query($query);
      }
      $stmt = self::prepare($query);
      $stmt->execute($args);
      return $stmt;
    } catch (PDOException $e) {
        throw new Exception($e->getMessage());
    }
  }

  /**
   * @param $query
   * @param array $args
   * @return mixed
   */
  public static function getRow($query, $args = [])  {
    return self::run($query, $args)->fetch();
  }

  /**
   * @param $query
   * @param array $args
   * @return array
   */
  public static function getRows($query, $args = [])  {
    return self::run($query, $args)->fetchAll();
  }

  /**
   * @param $query
   * @param array $args
   * @return mixed
   */
  public static function getValue($query, $args = [])  {
    $result = self::getRow($query, $args);
    if (!empty($result)) {
      $result = array_shift($result);
    }
    return $result;
  }

  /**
   * @param $query
   * @param array $args
   * @return array
   */
  public static function getColumn($query, $args = [])  {
    return self::run($query, $args)->fetchAll(PDO::FETCH_COLUMN);
  }

  public static function sql($query, $args = [])
  {
    self::run($query, $args);
  }
}

Заключение

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

Но, использование веб-фреймворков, типа Yii или Kohana, состоящих из нескольких сотен файлов, при разработке простых веб-приложений (например, сайтов-визиткок) не всегда целесообразно. Теперь мы умеем создавать красивую MVC модель, чтобы не перемешивать Php, Html, CSS и JavaScript код в одном файле.

Данная статья является скорее отправной точкой для изучения CMF, чем примером чего-то истинно правильного, что можно взять за основу своего веб-приложения. Возможно она даже вдохновила Вас и вы уже подумываете написать свой микрофреймворк или CMS, основанные на MVC. Но, прежде чем изобретать очередной велосипед с «блекджеком и шлюхами», еще раз подумайте, может ваши усилия разумнее направить на развитие и в помощь сообществу уже существующего проекта?!

Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Люкс-хост
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: