J04D0

                Никогда не пишите на Си, 
                если вы можете сделать это в AWK;

                Никогда не делайте это в AWK, 
                если sed может справиться с этим;

                Никогда не используйте sed, 
                когда tr может выполнять эту работу;

                Никогда не вызывайте tr, 
                когда достаточно cat;

                Избегайте использования cat, 
                когда это возможно.
                                           
                -- Законы программирования Тейлора

## РЕЛИГИОЗНЫЕ ВОЙНЫ
--------------------

1. Один инструмент -- одна цель (OTOG -- one tool one goal, т.е. не забивайте шурупы молотком. Или, что то же самое, не пытайтесь зашить порваную шкуру каменным топором).

2. Одно устройство -- одна цель. Клеточный автомат (для предотвращения обега из клетки :).

3. Один компьютер -- одна задача. DOS.

Справедливости ради стоит сказать, что в DOS можно было печатать параллельным фоновым процессом.

4. Многозадачная операционная система. Один инструмент -- одна цель.

UNICS. (1971, В те годы писали именно так)

5. Зарождение Perl (это было до Windows!), или кто выпустил "Лукавого":

Вот тогда я и внес свой маленький вклад в дело спасения мира. Как-то раз я перебирал в руках эти самые четки и размышлял о безнадежности (и случайности) моего существования, и вдруг мне пришла в голову одна мысль: а что, если расплавить несколько этих мистических бусинок и посмотреть, как изменится волшебная сила, если сделать из них одну большую бусину? Я зажег старую бунзеновскую горелку, выбрал свои любимые бусинки и сплавил их в одну большую. И что же -- ее волшебство оказалось более сильным, чем сумма волшебства ее частей!{*}

------
{*} This was when I made my small contribution to saving the world. I was rolling some of those very beads around in my fingers one day and pondering the hopelessness (and haplessness) of my existence, when it occurred to me that it might be interesting to melt down some of those mystical beads and see what would happen to their Magic if I made a single, slightly larger bead out of them. So I fired up the old Bunsen burner, picked out some of my favorite beads, and let them melt together however they would. And lo! the new Magic was more powerful than the sum of its parts and parcels.

Larry Wall's foreword to Randal Schwartz's "Learning Perl", 1e, 1987.
------

6. GUI, Rapid IDE (Borland, Lazarus, Padre, MS Visual..), 

Взлет и спад ООП эйфории. День сегодняшний -- стабильный полет на бреющей высоте.

## PHP7 НА WINDOWS 10.

Добавить пути:

  Control Panel -> 
    System -> 
      Advanced System Settings -> 
        Environment Variables -> 
          System Variables -> 
            Path

  C:\Program Files (x86)\GnuWin32\bin
  C:\PHP7

1. Установить PHP v.7.3 (VC15 x64 Thread Safe (2018-Dec-06 04:31:24))

  https://windows.php.net/download/
  
  + Zip [24.16MB]

2. Установить Flowgorithm (v.2.18.4)

3. Установить пакеты GnuWin32 

  Complete package, except sources,
  [v] Download sources during install

    http://gnuwin32.sourceforge.net/packages/gawk.htm
    http://gnuwin32.sourceforge.net/packages/ed.htm
    http://gnuwin32.sourceforge.net/packages/grep.htm
    http://gnuwin32.sourceforge.net/packages/sed.htm

## Задачи:

1. Ввести несколько чисел строкой. Вывести в столбик. Проверять валидность ввода.

2. Ввести натуральное число. Вывести цифры в столбик. Сортировать от наибольшего к наименьшему.

3. 

## КОНВЕРТЕР С FLO В FLOWGORITHM'S FPRG (XML) НА PHP
----------------------------------------------------

# Шаг 1. Здравствуй ОО-Мир.

  <?php
    class Hello {
        protected $msg = "Здравствуй ОО-Мир";

        public function speak() {
            print( $this->msg);
        }
    }
    $o = new Hello();
    $o->speak()
  ?>
  
Обратите внимание на местa, где исчезает знак доллара:

            v
   $o = new Hello();
   $this->msg
          ^
 
# Шаг 2. Главный цикл контроллера.

У программы контроллера три фазы: 

  setup (настройка) 
  loop  (работа)
  die   (вывод из эксплуатации)
  
Кому знакомы скетчи Arduino (setup, loop), скрипты на AWK (BEGIN, //, END) и т.п. -- увидят много общего. В PHP7 изменился механизм создания и уничтожения класса, если не хотите использовать deprecated технику работы с классами, почитайте здесь:

Warning: Old style constructors are DEPRECATED in PHP 7.0, and will be removed in a future version. You should always use __construct() in new code.

  http://php.net/manual/en/language.oop5.decon.php

Пример

  <?php
  class Awk {
    private $f;
    
    function __construct() {
      echo "BEGIN phase".PHP_EOL;
      echo PHP_EOL;
      $this->f = file(__FILE__);
      $this->loop();
    }
    
    function __destruct() {
      echo "END phase".PHP_EOL;
    }
    
    private function loop() {
      foreach( $this->f as $i ) {
        echo rtrim($i).PHP_EOL;
      }
    }
  }

  $o = new Awk();
  ?> 

# Шаг 3. Аргументы командной строки

  http://php.net/manual/en/reserved.variables.argv.php

Пример.

  <?php var_dump($argv); ?>
  
# Шаг 4. preg_match.

  http://php.net/manual/en/function.preg-match.php
  
  int preg_match ( 
    string $pattern, 
    string $subject, 
    array &$matches,
    int $flags = 0
  )

pattern -- The pattern to search for, as a string.

subject -- The input string.

matches -- Results of search. $matches[0] will contain the text that matched the full pattern, $matches[1] will have the text that matched the first captured parenthesized subpattern, and so on.

flags   -- flags can be a combination of the following flags: PREG_OFFSET_CAPTURE . If this flag is passed, for every occurring match the appendant string offset (in bytes) will also be returned. Note that this changes the value of matches into an array where every element is an array consisting of the matched string at offset 0 and its string offset into subject at offset 1.

Пример.

  <?php
    preg_match(
      '/(foo)(bar)(baz)/',
      'foobarbaz',
      $matches,
      PREG_OFFSET_CAPTURE
    );

    print_r( $matches);
  ?>

В результате получим: (уменьшил количество newline'ов)

  $ php pm.php | tr -d '\n' | sed 's/^Array(/Array  (\n/' | \
                 sed 's/)/)\n/g' | sed 's/  \+/  /g'
                 
  Array  (
    [0] => Array  (  [0] => foobarbaz  [1] => 0  )
    [1] => Array  (  [0] => foo  [1] => 0  )
    [2] => Array  (  [0] => bar  [1] => 3  )
    [3] => Array  (  [0] => baz  [1] => 6  )
  )

NOTE: Вот что действительно заняло уйму времени, так это понять, что $matches[$n] надо чомпать (chomp) .. с помощью функции chop !

# шаг 5. Верификация ввода

  <?php
  function input() {
      return fgets(STDIN);
  }

  function v( $against) {
    $f = true;
    while ( $f) {
        $s = trim( input());
        if ( 1 == preg_match( $against, $s)) {
          echo "You entered : " . $s . PHP_EOL;
          $f = false;
        }
        else
          echo "No. Please repeat : " . PHP_EOL;
    }
    return $s;
  }

  # echo "Enter 0 or 1 : " . PHP_EOL;
  # echo "Got " . v('/^0|1$/') . PHP_EOL;

  echo "Enter number (not negative integer) : " . PHP_EOL;
  # allows: 0 or [1-9][0-9]*
  echo "Got " . v('/^(0|[1-9][0-9]*)$/') . PHP_EOL;

  echo "Enter integer : " . PHP_EOL;
  # allows: [+-?]number
  echo "Got " . v('/^[+-]?(0|[1-9][0-9]*)$/') . PHP_EOL;

  echo "Enter float : " . PHP_EOL;
  # allows: [+-?]number\.?[0-9]*((e|E)[+-]?number)?
  echo 
    "Got " . 
    v('/^[+-]?(0|[1-9][0-9]*)\.?[0-9]*((e|E)[+-]?(0|[1-9][0-9]*))?$/') .
    PHP_EOL;
  ?>

# шаг 7. Весь конвертер (фрагменты).

  <?php
  class Awk {
    private $f;
    
    function __construct( $a) {
      # echo "BEGIN phase".PHP_EOL;
      echo PHP_EOL;
      if ( is_null($a)) 
        echo "Usage __FILE__ src.foo".PHP_EOL;
      else {
        $this->f = file( $a);
        $this->head();
        $this->loop();
        $this->foot();
      }
    }
    
    function __destruct() {
      # echo "END phase".PHP_EOL;
    }
    
    private function head() {
      echo "<?xml version=\"1.0\"?>".PHP_EOL;
      echo "<flowgorithm fileversion=\"2.11\">".PHP_EOL;
      echo "  <attributes>".PHP_EOL;
      echo "    <attribute name=\"name\" value=\"\"/>".PHP_EOL;
      echo "    <attribute name=\"authors\" value=\"\"/>".PHP_EOL;
      echo "    <attribute name=\"about\" value=\"\"/>".PHP_EOL;
      echo "    <attribute name=\"saved\" value=\"\"/>".PHP_EOL;
      echo "    <attribute name=\"created\" value=\"\"/>".PHP_EOL;
      echo "    <attribute name=\"edited\" value=\"\"/>".PHP_EOL;
      echo "  </attributes>".PHP_EOL;
    }
    
    private function foot() {
      echo "</flowgorithm>";
    }
    
    private function flo2fprg( $a) {
      if (1==preg_match(
        '/function +Main/',
        $a
      ))
        echo
          "  <function name=\"Main\" type=\"None\" variable=\"\">".
          PHP_EOL;
        
      if (1==preg_match(
        '/begin/',
        $a
      )) {
        echo "    <parameters/>".PHP_EOL;
        echo "  <body>".PHP_EOL;
      }

      if (1==preg_match(
        '/end +function/',
        $a
      )) {
        echo "  </body>".PHP_EOL;
        echo "  </function>".PHP_EOL;
      }
      
      if (1==preg_match(
        '/^#.*$/',
        $a,
        $matches
      ))
        # try .$matches[0].in Windows and in Unix, 
        # and you'll see what i mean.
        echo "    <comment text=\"". 
             chop($matches[0]) . 
             "\"/>" .PHP_EOL;
             
      if (1==preg_match(
        '/declare +int +([a-zA-Z][a-zA-Z0-9_]+)[^\[a-zA-Z0-9_]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) . 
             "\" type=\"Integer\" array=\"False\" size=\"\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +int +([a-zA-Z][a-zA-Z0-9_]+)\[([0-9]+)\]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"Integer\" array=\"True\" size=\"" .
             chop( $matches[2]) .
             "\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +real +([a-zA-Z][a-zA-Z0-9_]+)[^\[a-zA-Z0-9\._]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"Real\" array=\"False\" size=\"\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +real +([a-zA-Z][a-zA-Z0-9\._]+)\[([0-9]+)\]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"Real\" array=\"True\" size=\"" .
             chop($matches[2]) .
             "\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +string +([a-zA-Z][a-zA-Z0-9_]+)[^\[a-zA-Z0-9_]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"String\" array=\"False\" size=\"\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +string +([a-zA-Z][a-zA-Z0-9_]+)\[([0-9]+)\]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"String\" array=\"True\" size=\"" .
             chop($matches[2]) .
             "\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +boolean +([a-zA-Z][a-zA-Z0-9_]+)[^\[a-zA-Z0-9_]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"Boolean\" array=\"False\" size=\"\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/declare +boolean +([a-zA-Z][a-zA-Z0-9_]+)\[([0-9]+)\]/',
        $a,
        $matches
      )) 
        echo "    <declare name=\"" . chop($matches[1]) .
             "\" type=\"Boolean\" array=\"True\" size=\"" .
             chop($matches[2]) .
             "\"/>".PHP_EOL;
             
      if (1==preg_match(
        '/assign +([a-zA-Z][a-zA-Z0-9_]+) += +([^ ]+)/',
        $a,
        $matches
      )) 
        echo "    <assign variable=\"" . chop($matches[1]) .
             "\" expression=\"" .
             str_replace( "\"", "&quot;", chop( $matches[2])) .
             "\"/>".PHP_EOL;

      if (1==preg_match(
        '/assign +([a-zA-Z][a-zA-Z0-9_]+\[[0-9]+\]) += +([^ ]+)/',
        $a,
        $matches
      )) 
        echo "    <assign variable=\"" . chop( $matches[1]) .
             "\" expression=\"" .
             str_replace( "\"", "&quot;", chop( $matches[2])) .
             "\"/>".PHP_EOL;
             
      # TODO: input, output, if, call, while, for #
  }
    
    private function loop() {
      foreach( $this->f as $i ) {
        $this->flo2fprg( $i);
      }
    }
    
  }

  $o = new Awk( $argv[1]);
  ?> 
  
  
## Приложение А. Подстрочный автоперевод с ручной правкой
---------------------------------------------------------

GETTING STARTED WITH OBJECTED ORIENTED PROGRAMMING IN PHP 7
НАЧАЛО РАБОТЫ С ОБЪЕКТНО-ОРИЕНТИРОВАННЫМ ПРОГРАММИРОВАНИЕМ В PHP 7

  https://www.brainbell.com/tutorials/php/php7-oop-beginners.html

PHP, an open source language, allow programmers to quickly develop error-free programs using procedural and objected-oriented programming techniques.
~
PHP, язык с открытым исходным кодом, позволяет программистам быстро разрабатывать безошибочные программы с использованием процедурных и объектно-ориентированных методов программирования.

## Procedural programming
## Процедурное программирование

A procedural programming includes functions (methods) that can be called from the main flow of the program. The flow of the program jumps to the function (method), executes the code within the module, and then returns to the next statement in the main flow of the program.
~
Процедурное программирование включает функции (методы), которые можно вызывать из основного потока программы. Поток программы переходит к функции (методу), выполняет код внутри модуля и затем возвращается к следующему оператору в основном потоке программы.

## Object-oriented programming (OOP)
## Объектно-ориентированное программирование (ООП)

  <?php

  class User {
    private $name;
    private $gender;
    public  $age;
  }
  ?>
  
OOP is a design philosophy that uses objects and methods rather than linear concepts of procedures and tasks (procedural programming) to accomplish programmatic goals. An object is a self-sustainable construct that enables re-usability of code. A method specifies one operation without providing any details to describe how the operation should be carried out.
~
ООП -- это философия дизайна, которая использует объекты и методы, а не линейные концепции процедур и задач (процедурное программирование) для достижения программных целей. Объект -- это самодостаточная конструкция, которая позволяет повторно использовать код. Метод определяет одну операцию без предоставления каких-либо подробностей для описания того, как должна выполняться операция.

## Advantages of OOP
## Преимущества ООП

Object-oriented programming (OOP) has some advantages over procedural programming: modularity, code re-usability, information hiding, and debugging ease.
~
Объектно-ориентированное программирование (ООП) имеет некоторые преимущества перед процедурным программированием: модульность, повторное использование кода, сокрытие информации и легкость отладки.

# Modularity
# Модульность

OOP provides a clear modular structure for programs. Modularity refers to the concept of making multiple modules first and then linking and combining them to form a complete system. Modularity enables re-usability and minimizes duplication.
~
ООП обеспечивает четкую модульную структуру программ. Модульность относится к концепции создания нескольких модулей сначала, а затем к их сцеплению и объединению для формирования полной системы. Модульность позволяет повторно использовать код и минимизировать дублирование.

# Reusability
# Повторное использование

Code can be re-use, without modification, to perform a specific service regardless of what application uses the code.
~
Код может быть повторно использован без изменений для выполнения конкретной службы независимо от того, какое приложение использует этот код.

# Information-hiding
# Сокрытие информации

The detail of internal implementation of a module (class) remain hidden from the outside world.
~
Детали внутренней реализации модуля (класса) остаются скрытыми от внешнего мира.

# Debugging
# Отладка

Easier to fix problems because the module (class) is independent from other pieces of code. Modifying one piece of code doesn’t impact other pieces of code in the application.
~
Легче исправлять проблемы, потому что модуль (класс) не зависит от других частей кода. Изменение одного фрагмента кода не влияет на другие фрагменты кода в приложении.

## OOP fundamentals
## Основы ООП

# Class
# Класс

A class is a template for creating objects.
~
Класс -- это шаблон для создания объектов.

In PHP a class is a collection of variables and functions working with these variables.
~
В PHP класс представляет собой набор переменных и функций, работающих с этими переменными.

To define a class, the class keyword is used, followed by a name and a code block delimited by curly braces.
~
Для определения класса используется ключевое слово class, за которым следует имя и блок кода, ограниченный фигурными скобками.

  class User {

  }

# Properties
# Свойства

Class member variables are called properties
~
Переменные членов класса называются свойствами

In PHP, class member variables are called “properties” (also “attributes” or “fields”). They are defined by using one of the keywords public, protected or private, followed by a normal variable declaration.
~
В PHP переменные-члены класса называются «свойствами» (также «атрибутами» или «полями»). Они определяются с использованием одного из ключевых слов public, protected или private, за которым следует объявление нормальной переменной.

  class User{
    public $name;
  }

# Method
# Метод

A method is a procedure associated with an object (similar to PHP functions)
~
Метод -- это процедура, связанная с объектом (подобно функциям PHP)

A function (method) is a piece of code which may take some input in the form of parameter and does some processing and returns a value.
~
Функция (метод) -- это фрагмент кода, который может принимать некоторый ввод в виде параметра и выполняет некоторую обработку и возвращает значение.

In OOP, a method is a part of a class and included in any object of that class. You can define method by using one of the keywords public, protected or private, followed by a normal name declaration.
~
В ООП метод является частью класса и включен в любой объект этого класса. Вы можете определить метод, используя одно из ключевых слов public, protected или private, за которым следует декларация нормального имени.

  class User{
    public $name;

    public function setName(){

    }

  }

## Properties and methods visibility
## Свойства и видимость методов

The property defined in above class were tagged as public. That means that it is accessible to anyone, or more precisely, from anywhere. This is called the visibility of the property or method.
~
Свойство, определенное выше, было помечено как общедоступное. Это означает, что он доступен любому, а точнее, откуда угодно. Это называется видимостью свойства или метода.

# private visibility
# частная видимость

This type allows access only to members of the same class. Members declared as private may only be accessed by the class that defines the member.
~
Этот тип позволяет получить доступ только к членам одного класса. Участникам, объявленным как private, может быть доступен только класс, определяющий участника.

Use this type if you want variable/function (method) to be visible in its own class only.
~
Используйте этот тип, если вы хотите, чтобы переменная/функция  (метод) была видимой только в своем классе.

  class User{
    //can be accessible within the same class
    private $name;
  }

# protected visibility
# защищенная видимость

This type allows access to members of the same class and instances from classes that inherit from that one only.
~
Этот тип позволяет получить доступ к членам одного класса и экземпляров из классов, которые наследуют только от этого.

Use this type if you want to make variable/function (method) to be visible in all classes that extend current class including the parent class.
~
Используйте этот тип, если вы хотите сделать переменную / функцию (метод) видимой во всех классах, которые расширяют текущий класс, включая родительский класс.

  class User {
    //accessible for same class and its child classes
    protected $name;
  }

# public visibility
# public visibility

This type refers to a property or method that is accessible from anywhere. Any classes or code in general from outside the class can access it.
~
Этот тип относится к свойству или методу, доступному из любого места. Любые классы или код вообще извне класса могут получить к нему доступ.

Use this type if you want to make variable/function available from anywhere, other classes and instances of the object.
~
Используйте этот тип, если вы хотите сделать переменную / функцию доступной из любого места, других классов и экземпляров объекта.

  class User {
    //accessible from anywhere
    public $name;
  }

## Object
## Объект

An instance of a class is called object.
~
Экземпляр класса называется объектом.

Object refers to a particular instance of a class where the object can be a combination of variables, functions (methods), and data structures.
~
Объект относится к конкретному экземпляру класса, в котором объектом может быть комбинация переменных, функций (методов) и структур данных.

  // Instance (or object) of User class
  $user = new User();

Creating a PHP class : example
~
Создание класса PHP: пример

  <?php

  class User {

  }

# Set private properties
# Установить частные свойства

Private visibility: Fatal error if try to access from outside the class
~
Частная видимость: фатальная ошибка при попытке доступа извне класса

  <?php

  class User {
    private $name;
    private $gender;
  }

# Set public properties
# Установить общедоступные свойства

Public visibility: can be access and modify from anywhere
~
Общественная видимость: доступ и изменение из любого места

  <?php

  class User {
    private $name;
    private $gender;
    public  $age;
  }

# Set initialized properties (or properties with default value)
# Установить инициализированные свойства (или свойства со значением по умолчанию)

  <?php

  class User {
    private $name;
    private $gender;
    public $age;
    private $department = 'Mechanical';
  }

# Set class methods
# Установить методы класса

  <?php

  class User {
    private $name;
    private $gender;
    public $age;
    private $department = 'Mechanical';
   
    /* set value to 'private $name' property */
    public function setName($name){
      $this->name = $name;
    }
   
    /* get value from 'private $name' property */
    public function getName(){
      return $this->name;
    }
  }

# The complete class
# Полный класс

  <?php

  class User {
    private $name;
    private $gender;
    public $age;
    private $department = 'Mechanical';
   
    public function setName($name){
      $this->name = $name;
    }
    public function getName(){
      return $this->name;
    }

    public function setGender($gender){
      $this->gender = $gender;
    } 
    public function getGender(){
      return $this->gender;
    }

    public function setDepartment($dep){
      $this->department = $dep;
    }
    public function getDepartment(){
      return $this->department;
    }
  }

# Making instances of the class
# Создание экземпляров класса

  $user = new User();

  Assign value to instance variables

  $user->setName('Sheri');
  $user->setGender('F');

  //public property : no error, accessible from anywhere
  $user->age = 30; 

  //Fatal error: Cannot access private property
  //Private and protected methods can not be access directly
  $user->department = 'Computer';

  //The right way to assign value for protected and private methods
  $user->setDepartment('Computer');

  Fetch and print instance variables value

  echo $user->getName();
  echo $user->getDepartment();
  echo $user->age;

  //Fatal error: Cannot access private property User::$department
  echo $user->department;

  /* You can make as many instance as you want */
  $user2 = new User();

  //prints Mechanical (default value for all instances)
  echo $user2->getDepartment();

  //changed the default department
  $user2->setDepartment('Computer');

## Encapsulation, Polymorphism and Inheritance
## Инкапсуляция, полиморфизм и наследование

PHP provides features to implement an object oriented model. These features includes encapsulation, inheritance and polymorphism.
~
PHP предоставляет функции для реализации объектно-ориентированной модели. Эти функции включают инкапсуляцию, наследование и полиморфизм.

# Encapsulation or information hiding
# Инкапсуляция или сокрытие информации

Encapsulation is just wrapping some data in an object. The term “encapsulation” is often used interchangeably with “information hiding”.
~
Инкапсуляция -- это просто перенос некоторых данных в объект. Термин «инкапсуляция» часто используется взаимозаменяемо с «скрытием информации».

Hiding the internals of the object protects its integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state.
~
Скрытие внутренних объектов объекта защищает его целостность, не позволяя пользователям устанавливать внутренние данные компонента в недопустимое или несогласованное состояние.

You can use encapsulation if the properties of an object are private, and the only way to update them is through public methods.
~
Вы можете использовать инкапсуляцию, если свойства объекта являются частными, и единственный способ их обновления - это публичные методы.

For example in this code we can protect our User objects from setting an invalid gender parameter.
~
Например, в этом коде мы можем защитить объекты User от установки недопустимого параметра gender.

  class User {
    private $name;
    private $gender;

    public function getName() {
      return $this->name;
    }

    public function setName($name) {
      $this->name = $name;
      return $this;
    }

    public function getGender() {
      return $this->gender;
    }

    public function setGender($gender) {
      if ('male' !== $gender and 'female' !== $gender) {
       throw new Exception('Set male or female for gender');
      }
      $this->gender = $gender;
      return $this;
    }
  }

  $user = new User();
  $user->setName('Michal');
  $user->setGender('male');

In above example we should assign male or female value for setGender method or it will print Fatal error: Uncaught exception 'Exception' with message 'Set male or female for gender'.
~
В приведенном выше примере мы должны назначить значение для метода setGender для мужчин или женщин или распечатать Fatal error: исключить исключение «Исключение» с сообщением «Установить мужчину или женщину для пола».

# Polymorphism
# Полиморфизм

Ability to process objects differently. An integral part of polymorphism is the common interface.
~
Возможность обрабатывать объекты по-разному. Неотъемлемой частью полиморфизма является общий интерфейс.

Polymorphism is a design pattern in which classes have different functionality while sharing a common interface. You can define an interface in PHP using interface or abstract classes.
~
Полиморфизм -- это шаблон проектирования, в котором классы имеют разную функциональность при совместном использовании общего интерфейса. Вы можете определить интерфейс в PHP с помощью интерфейса или абстрактных классов.

This example will describe the general concept of polymorphism, and how it can easily be deployed in PHP.
~
В этом примере будет описана общая концепция полиморфизма и как ее можно легко развернуть в PHP.

In the example given below, the interface with the name of Shape commits all the classes that implement it to define an abstract method with the name of area().
~
В приведенном ниже примере интерфейс с именем Shape фиксирует все классы, которые его реализуют, для определения абстрактного метода с именем area ().

Step 1 : declaring interface using interface keyword.
~
Шаг 1: объявление интерфейса с использованием ключевого слова интерфейса.

  interface Shape {
  }

Step 2: add method (methods can be defined in the interface without the body).
~
Шаг 2: добавить метод (методы могут быть определены в интерфейсе без тела).

  interface Shape {
    public function area();
  }

Step 3: create Circle class that implements the Shape interface by putting into the area() method the formula that calculates the area of circles:
~
Шаг 3: создайте класс Circle, который реализует интерфейс Shape, помещая в метод area () формулу, которая вычисляет область кругов:

  class Circle implements Shape {
    private $radius; 
   
    public function __construct($radius) {
    $this -> radius = $radius;
    }
   
    public function area() {
    return $this -> radius * $this -> radius * pi();
    }
  }

Step 4: The rectangle class also implements the Shape interface but defines the method area() with a calculation formula that is suitable for rectangles:
~
Шаг 4: Класс прямоугольника также реализует интерфейс Shape, но определяет область метода () с формулой расчета, подходящей для прямоугольников:

  class Rectangle implements Shape {
    private $width; 
    private $height;
   
    public function __construct($width,$height) {
    $this -> width  = $width;
    $this -> height = $height;
    }
   
    public function area() {
    return $this -> width * $this -> height;
    }
  }

By implementing interface we can be sure that all of the objects calculate the area with the method that has the name of area(), whether it is a rectangle object or a circle object (or any other shape).
~
Внедряя интерфейс, мы можем быть уверены, что все объекты вычисляют область с помощью метода, который имеет имя area (), будь то объект прямоугольника или объект окружности (или любая другая форма).

  $rect = new Rectangle(3,3);
  echo $rect -> area();

  $circ = new Circle (5);
  echo $circ -> area();

# Inheritance
# Наследование

Take properties of existing objects
~
Возьмите свойства существующих объектов

Since a class is simply a collection of related functions and variables, one way of adding new functionality is to amend the code. In the early stages of development, this is usually the correct approach, but a fundamental aim of OOP is reusability and reliability. There’s no need to code everything from scratch, you can base a new class on an existing one. OOP classes are extensible through inheritance.
~
Поскольку класс -- это просто набор связанных функций и переменных, одним из способов добавления новых функций является изменение кода. На ранних этапах разработки это, как правило, правильный подход, но основная цель ООП - повторное использование и надежность. Нет необходимости кодировать все с нуля, вы можете создать новый класс на существующем. Классы ООП могут быть расширены через наследование.

A child class or subclass in OOP can inherit all the features of its parent or superclass, adapt some of them, override existing methods and properties, and add new ones of its own.
~
Детский класс или подкласс в ООП может наследовать все функции своего родителя или суперкласса, адаптировать некоторые из них, переопределять существующие методы и свойства и добавлять новые свои собственные.

  class Human {
    protected $name;
   
    public function __construct( $name){
      $this->name = $name;
    }
  }

In order to declare that one class inherits the code from another class, we use the extends keyword.
~
Чтобы объявить, что один класс наследует код из другого класса, мы используем ключевое слово extends.

  class Person extends Human {
    /* no constructor, adapted the parent constructor */
    public function getName(){
      /*Will return name property defined in parent class*/
      return $this->name; 
    }
  }

The above code demonstrated that how Person class inherited the parent constructor and added new method as per our need.
~
Вышеприведенный код показал, что класс Person унаследовал родительский конструктор и добавил новый метод в соответствии с нашей потребностью.

  //constructor function inherited from the parent
  $person = new Person('Kelly');
  echo $person->getName();

## Abstract class, Interface, composition and aggregation
## Абстрактный  класс, интерфейс, состав и агрегация

Both Composition and Aggregation are the form of association between two objects, but there is a subtle difference between composition and aggregation. In this tutorial we'll also discuss Abstract classes and Interface.
~
Как состав, так и агрегация являются формой ассоциации между двумя объектами, но есть тонкая разница между композицией и агрегацией. В этом уроке мы также обсудим абстрактные классы и интерфейс.

# Abstract class
# Абстрактный класс

A class designed only as a parent from which sub-classes may be derived.
~
Класс, созданный только как родитель, из которого могут быть получены подклассы.

  + Abstract classes are classes that may contain abstract method(s).
~
  + Абстрактные классы - это классы, которые могут содержать абстрактный метод (ы).

  + An abstract method is a method that is declared, but contains no implementation.
~
  + Абстрактный метод - это метод, объявленный, но не содержащий реализации.
  
  + Abstract classes can not be instantiated, and require subclasses to provide implementations for the abstract methods.
~
  + Абстрактные классы не могут быть созданы и требуют, чтобы подклассы предоставляли реализации абстрактных методов.

To make a class abstract, add the keyword abstract in front of class and the class name in the class definition.
~
Чтобы создать абстрактный класс, добавьте ключевое слово abstract перед классом и имя класса в определении класса.

  abstract class Products {
    protected $name;
    protected $type;

    public function __construct($name, $type){
      $this->type = $type;
      $this->name = $name;
    }

    public function getType() {
      return $this->type;
    }

    public function getName() {
      return $this->name;
    }

    abstract public function getTypeName();
  }

Abstract classes can not be instantiated, so we’ll extend it by making a child class product. An abstract function also declared in above example and we know, methods marked abstract in the parent’s class declaration must be defined by the child class.
~
Абстрактные классы не могут быть созданы, поэтому мы расширим его, создав дочерний класс. Абстрактная функция также объявлена ​​в приведенном выше примере, и мы знаем, что методы, помеченные как абстрактные в объявлении класса родителя, должны определяться дочерним классом.

  class Product extends Products {
    public function getTypeName() {
      return $this -> name .':'. $this -> type;
    }
  }

  $product = new Product('Paper','80g');
  echo $product->getTypeName();

# Interfaces
# Интерфейсы

An interface allows the computer to enforce certain properties on an object (class). It is actually a concept of abstraction and encapsulation.
~
Интерфейс позволяет компьютеру обеспечивать выполнение определенных свойств объекта (класса). Это на самом деле концепция абстракции и инкапсуляции.

An interface is very similar to an abstract class, but it has no properties and cannot define how methods are to be implemented. Instead, it is simply a list of methods that must be implemented.
~
Интерфейс очень похож на абстрактный класс, но он не имеет свойств и не может определить, как методы должны быть реализованы. Вместо этого это просто список методов, которые должны быть реализованы.

In its most common form, an interface is a group of related methods with empty bodies. A child class can implement multiple interfaces.
~
В своей наиболее распространенной форме интерфейс представляет собой группу связанных методов с пустыми телами. Детский класс может реализовывать несколько интерфейсов.

  interface Animal {
    public function breath();
    public function eat();
  }

  class Dog implements Animal{
    //new method
    public function bark() {
      return 'wof';
    }
   
    //implemented methods
    public function breath() {
      return 'breathing';
    }

    public function eat() {
      return 'eating';
    }
  }

  $dog = new Dog();
  echo $dog -> breath(); //breathing
  echo $dog -> bark(); //wof
  echo $dog -> eat(); //eating

## Composition and Aggregation
## Состав и агрегация

# relationships between objects.
# отношения между объектами.

Composition is an important concept in PHP. In this design pattern an object creates another object. Aggregation occurs when an object is composed of multiple objects.
~
Композиция является важной концепцией в PHP. В этом шаблоне проектирования объект создает другой объект. Агрегация возникает, когда объект состоит из нескольких объектов.

Composition is effectively an ownership relationship, while aggregation is a “contains” relationship. In composition, the parts can not exist outside the thing that contains them, but individual things can exist on their own as unique entities in aggregation.
~
Композиция фактически является отношением собственности, а агрегирование - «содержит» отношения. В композиции части не могут существовать вне того, что их содержит, но отдельные вещи могут существовать сами по себе как уникальные сущности в совокупности.

# Composition example
# Пример композиции

  class Author {
    private $name;
    private $email;

    public function __construct($name,$email){
      $this->name = $name;
      $this->email = $email;
    }

    public function getName(){
      return $this->name;
    }

    public function getEmail(){
      return $this->email;
    }
  }

  class Book {
    //using array to allow multiple authors
    private $authors = array();
    private $price;
    private $name;

    public function __construct($name,$price){
      $this->name = $name;
      $this->price = $price;
    }

    public function setPrice($price){
      $this->price = $price;
    }

    public function getPrice(){
      return $this->price;
    }

    public function getName(){
      return $this->name;
    }

    public function addAuthor($name,$email){
      $this->authors[] = new Author($name,$email);
    }

    public function getAuthors(){
      return $this->authors;
    }
  }

  $book = new Book('Book Name',10.0);
  $book -> addAuthor('Kelly','kelly@brainbell.com');
  $book -> addAuthor('Ken','ken@brainbell.com');

  /* print book info */
  echo $book -> getName();
  echo $book -> getPrice();

  /* print book's authors info */
  $authors = $book -> getAuthors(); //Array of authors
  foreach ($authors as $author) {
    echo $author -> getName();
    echo $author -> getEmail();
  }

# Aggregation example
# Пример агрегации

  class Author {
    private $name;
    private $email;

    public function __construct($name,$email) {
      $this->name = $name;
      $this->email = $email;
    }
   
    public function getName() {
      return $this->name;
    }
   
    public function getEmail(){
      return $this->email;
    }
  }

  class Book {
    private $authors;
    private $price;
    private $name;

    public function __construct($name,$price,$author){
      $this->name = $name;
      $this->price = $price;
      $this->author = $author;
    }

    public function setPrice($price){
      $this->price = $price;
    }

    public function getPrice(){
      return $this->price;
    }

    public function getName(){
      return $this->name;
    }
    public function getAuthor(){
      return $this->author;
    }
  }

  $author = new Author('Kelly','kelly@brainbell.com');
  $book = new Book('Book Name',10.0,$author);

  echo $book->getName(); //Book Name
  echo $book->getAuthor() -> getName();  //Kelly
  echo $book->getAuthor() -> getEmail(); //kelly@brainbell.com
  
## Приложение Б. PHP скрипт для автоматического выбора вариантов.

Варианты на 30 человек (150 задач).

  <?php
    $a = array();
    
    while ( sizeof($a) < 150) {
      $n = rand(1,150);
      if ( !in_array( $n, $a)) array_push( $a, $n);
    }
    
    for ($r=1; $r<=30; $r++) {
      echo '['.$r.'] : ';
      for ($c=1; $c<=5; $c++)
        echo $a[5*($r-1)+$c].' ';
      echo PHP_EOL;
    }
  ?>

## Приложение В. Валидатор введенного числа

  <?php
  function input() {
      return fgets(STDIN);
  }

  function v( $against) {
    $f = true;
    while ( $f) {
        $s = trim( input());
        if ( 1 == preg_match( $against, $s)) {
          echo "You entered : " . $s . PHP_EOL;
          $f = false;
        }
        else
          echo "No. Please repeat : " . PHP_EOL;
    }
    return $s;
  }

  # echo "Enter 0 or 1 : " . PHP_EOL;
  # echo "Got " . v('/^0|1$/') . PHP_EOL;

  echo "Enter number (not negative integer) : " . PHP_EOL;
  # allows: 0 or [1-9][0-9]*
  echo "Got " . v('/^(0|[1-9][0-9]*)$/') . PHP_EOL;

  echo "Enter integer : " . PHP_EOL;
  # allows: [+-?]number
  echo "Got " . v('/^[+-]?(0|[1-9][0-9]*)$/') . PHP_EOL;

  echo "Enter float : " . PHP_EOL;
  # allows: [+-?]number\.?[0-9]*((e|E)[+-]?number)?
  echo 
    "Got " . 
    v('/^[+-]?(0|[1-9][0-9]*)\.?[0-9]*((e|E)[+-]?(0|[1-9][0-9]*))?$/') .
    PHP_EOL;
  ?>

