За последние 24 часа нас посетили 21407 программистов и 1021 робот. Сейчас ищут 703 программиста ...

Lerma - Драйвера для работы с БД MySQL

Тема в разделе "PHP и базы данных", создана пользователем MouseZver, 23 сен 2017.

  1. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Всем злое бу!
    В свободное время решил на этот раз написать библиотеку "Лерма" по работе с различными Бд.
    Сама библиотека пока не реализована со своей миграцией и составлений структур запроса, а лишь ее драйвера ( обвертки ).
    Сталкивался с некими нюансами в MySQLi, по решению которых не хватала практика.
    И все же за несколько дней ( план, составление на будущее привязки к Lerma, реализация ), завершил.
    Старался по мере возможностей использовать некие анспекты более лаконичнее, дабы не написать совсем тупой мусор.

    PHP:
    1. $arguments = array_values ( $arguments );
    2.  
    3. extract ( $arguments, EXTR_PREFIX_ALL, 'bind' );
    4.  
    5. $a = [];
    6.  
    7. foreach ( $arguments AS $k => $arg )
    8. {
    9.     $a[] = &${ 'bind_' . $k };
    10. }
    11.  
    12. $arguments = array_merge ( [ implode ( '', $types ) ], $a );
    13.  
    14. $this -> statement -> bind_param( ...$arguments );
    15. #call_user_func_array ( [ $this -> statement, 'bind_param' ],  );
    Это писец..

    Самый большой затык предоставила функция bind_param, где нужно было создать переменные как ссылки.
    Почему закомментина call_user_func_array ?
    Поздновато спомнил об операторе ... и с ее возможностью не только принимать n кол-во аргументов, но и передавать их.

    В остальных случаях ( хорошо что документацию скачал - без инета кодил ), листал доки по работе с MySQLi.
    Познакомился с ее api о передаче небуфер данных.

    Есть несколько мест в написанном коде где сомневаюсь в правильном и качественном применении.
    Особого тут ничего нет, так как PDO ближе схоже с моейм задумкой по интеграции в мигрант Лермы.

    Данные драйвера находятся в тест стадии и будут еще переписываться, что добавляться, что изменяться в более верный подход.
    По стилю вывода информации пока выбраны стандартные NUM / ASSOC / BOTH / OBJ выводы.

    Для тестов создал файлик index.php в папке drivers
    PHP:
    1. <?php
    2.  
    3. error_reporting ( E_ALL | E_STRICT );
    4.  
    5. $lerma = require ( dirname ( __FILE__, 3 ) . '/Interfaces/Lerma/IDrivers.php' );
    6. $lerma = require ( dirname ( __FILE__, 3 ) . '/Configures/Lerma.php' );
    7. $params = $lerma -> {$lerma -> driver};
    8.  
    9.  
    10. $a = require $lerma -> driver . '.php';
    11.  
    12. $s = $a -> prepare( 'SELECT * FROM usraccount WHERE id = ?' ) -> execute( [ 5 ] ) -> fetch();
    13.  
    14.  
    15.  
    16.  
    17. /*
    18. PDO::FETCH_ASSOC 2 MYSQLI_NUM
    19. PDO::FETCH_NUM 3 MYSQLI_BOTH
    20. PDO::FETCH_BOTH 4
    21. PDO::FETCH_OBJ 5
    22. MYSQLI_ASSOC 1
    23.  
    24. pdo[
    25.     1 => PDO::FETCH_NUM,
    26.     2 => PDO::FETCH_ASSOC,
    27.     3 => PDO::FETCH_BOTH,
    28.     4 => PDO::FETCH_OBJ
    29. ]
    30. MySQLi[
    31.     1 => MYSQLI_NUM
    32.     2 => MYSQLI_ASSOC
    33.     3 => MYSQLI_BOTH
    34.     4 => 4
    35. ]
    36. */
    Прилагающий конфиг:
    PHP:
    1. <?php
    2.  
    3. return new class
    4. {
    5.     private const USER = 'root';
    6.     private const PASSWORD = '';
    7.  
    8.     # Назначение драйвера для подключения базы данных
    9.    public $driver = mysqli::class;
    10.  
    11.     # Параметры для драйвера mysqli
    12.    public $mysqli = [
    13.         'host' => '127.0.0.1',
    14.         'user' => self::USER,
    15.         'password' => self::PASSWORD,
    16.         'dbname' => 'single',
    17.         'port' => 3306
    18.     ];
    19.  
    20.     # Параметры для драйвера PDO
    21.    public $PDO = [
    22.         'dns' => 'mysql:host=127.0.0.1;dbname=single;charset=utf8',
    23.         'user' => self::USER,
    24.         'password' => self::PASSWORD,
    25.         'options' => [
    26.             PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    27.             PDO::ATTR_EMULATE_PREPARES => FALSE,
    28.         ]
    29.     ];
    30. };
    В переменную driver заносится название подключаемого скрипта MySQLi / PDO.
    Особого нет.. конфиг как конфиг, но нет...
    Переменные для настроек расширений в драйверах должны идти четко последовательно как назначенны в массивах для каждого.
    Тобишь не допустим рандом, для примера:
    PHP:
    1. $mysqli = [
    2.     'port' => 3306,
    3.     'host' => '127.0.0.1',
    4.     'password' => self::PASSWORD,
    5.     'dbname' => 'single',
    6.     'user' => self::USER
    7. ];
    В итоге получаю то что хотелось:
    PHP:
    1. <?php
    2.  
    3. # Обычный запрос
    4. $ca = $a -> query( 'SELECT * FROM usraccount WHERE id BETWEEN 5 AND 25' );
    5.  
    6. if ( $ca -> rowCount() > 0 )
    7. {
    8.     var_dump ( 'query', $ca -> fetch( 4 ), '----' );
    9.     # или -> fetchAll( 4 )
    10. }
    11.  
    12. $ca = $a -> prepare( 'SELECT * FROM usraccount WHERE id IN ( ?,?,? )' ) -> execute( [ 4, 27, 666 ] );
    13.  
    14. if ( $ca -> rowCount() > 0 )
    15. {
    16.     var_dump ( 'prepare', $ca -> fetch( 4 ), '----' );
    17.     # или -> fetchAll( 4 )
    18. }
    Жду критики :)
    --- Добавлено ---
    Забыл
    https://github.com/MouseZver/My-garbage-code/tree/master/Lerma
     
    [vs] и Алекс8 нравится это.
  2. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    не знаю как кому)) но мне бы хотелось что бы в оператор IN можно было сразу массив отправлять)
    что то типа такого))
    PHP:
    1.                 $smcFunc['db_query']('', '
    2.                    DELETE FROM {db_prefix}themes
    3.                    WHERE variable = {string:current_column}
    4.                        AND value NOT IN ({array_string:new_option_values})
    5.                        AND id_member > {int:no_member}',
    6.                     array(
    7.                         'no_member' => 0,
    8.                         'new_option_values' => $newOptions,
    9.                         'current_column' => $context['field']['colname'],
    10.                     )
    11.                 );
     
  3. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Это сама Лерма будет делать :)
    PHP:
    1. Lerma::select( [ 4, 27, 666 ], function ( Placebo $Placebo )
    2. {
    3.    $Placebo -> column( ... );
    4.    $Placebo -> table( ... );
    5.    $Placebo -> where( придумать ) -> in( [ 1,2,3 ] ) ... ;
    6.    $Placebo -> order( 'DESC' );
    7. } );
     
    Алекс8 нравится это.
  4. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Это не драйвер, а бибилиотека-обертка. Драйверы - это про другое.
    --- Добавлено ---
    А если в where нужны подзапросы? А если нужно бабахнуть что-то
    [​IMG]
    ?
     

    Вложения:

    #4 Fell-x27, 23 сен 2017
    Последнее редактирование: 23 сен 2017
  5. Алекс8

    Алекс8 Активный пользователь

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    ИМХО)) лучше сделать несколько простых запросов - чем один вложенный))
    а так то мне больше нравится тип записи такой как у меня в примере)) чем вот такой как в AR Yii2))
     
  6. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Это не всегда возможно. И не всегда правильно. Если бы я эту дуру растащил на пачку запросов поменьше и жонглировал этим всем руками в оперативке, а не отдал на совсеть MySQL, то оно бы выполнялось раз в 10 дольше и жрало бы соответственно.
     
  7. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    для этого там "придумать", в этом пока загвостка в будущем буду решать :oops:
     
  8. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Я не просто так про это спросил. Это камень предкновения для кверибилдеров. SQL - это язык. Нельзя его просто взять и упихнуть в пару команд, к сожалению. В итоге ты либо ограничиваешь пользователя, либо изобретаешь собственный SQL, где вместо операторов будут команды твои, что нифига не упрощает, либо просто забьешь на кверибилдинг и будешь принимать чистые запросы под бинды. Ты загляни в этот ужас, что я скинул. Там разве что каким-то чудом нет джоинов. В остальном там куча IF-ов, работы с датами и один EXISTS. Это тоже все придется реализовывать.

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

    Тут вся логика в том, что человек, не знающий тот же MySQL и с кверибилдером хрен что сделает, потому как все равно полностью от особенностей и логики конкретной БД ты не абстрагируешься. А человеку знающему MySQL проще долбануть запрос "как есть". Хотя бы по причине того, что чистые запросы разрабатывать можно прямо в IDE, подцепленной к БД, в рилтайме, я вот скрин из Штормов скинул. Там это безумно удобно делать. А мне теперь осталось только скопипастить эту дуру в проект. В случае же с кверибилдерами надо еще будет день голову ломать, как этот запрос на кверибилдер переписать.И уповать на то, что он правильно "скомпилируется".
     
  9. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    видел и по хуже когда листал темы про JOINы :)
    Будет моя проблема, есть над чем голову поломать
    --- Добавлено ---
    +
    и тогда не будет нужды в миграции. В итоге получаем скукоту на несколько сотен строк - весь проект o_O
     
  10. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.155
    Симпатии:
    1.769
    Адрес:
    :сердА
    Ды JOIN-ы это не сложно. С ними один раз плотно поработать и они становятся естественны и прозрачны. Это только поначалу они голову ломают. В мускуле есть вещи поприкольнее. Например case ... when. Или те же IF-ы, которых несколько видов и у каждого своя логика. И я о тех конструкциях, что используются в запросах, а не в хранимых процедурах.
    Ну дык KISS же. Чем проще, тем лучше.

    Хз, у меня в проекте тоже самописная либа для работы с БД вертится. Ее интерфейс сводится к передаче ей запроса, флага транзакции(нужна или нет), флага, отвечающего за вид возвращенного результата, имени свойства, которое нужно использовать вместо номеров строк, если, конечно это нужно. Порой пригождается. Из этого всего обязательный параметр только запрос.

    Работа с ней выглядит так:
    PHP:
    1. $data = API::send_query($query)['result'] ?? [];
    усе. В переменной $data будет лежать результирующий массив. Можно убрать "['result']" и получить от функции ответ, содержаний как результат выборки/ошибку, так и пачку служебных данных, типа последнего id, если юзался insert, сведений об обработке запроса и по мелочи.
     
  11. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Сорри за оффтоп, но вспомнил недавний коммент:
    и подумал, как бы сам @MouseZver ответил? Наверное, что-то вроде: "Образцовый говнокод! Немного договнокодить и можно на чемпионат по говнокоду отправлять" :D
     
    MouseZver нравится это.
  12. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Видео курсы Попова отдыхают перед таким "..."
     
  13. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Да ну. Никто же не заставляет всё делать через кверибилдер. Что удобно через него - делаешь через него. Что удобно напрямую - делаешь напрямую. Я уже писал как-то, для меня главное достоинство Query Builder, что его можно через пол системы прогнать, до того, как формируется окончательный запрос. Я это использую для динамического навешивания комбинаций фильтров и прочего.

    Естественно, чтоб пользоваться кверибилдером, знать SQL необходимо - об этом даже речи не ведётся.
     
  14. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    К слову, сам по себе query builder имеет смысла разве что как удобная обертка, т.к. стандартные пыховские интерфейсы слишком многословны. По настоящему удобно становится тогда, когда это все обвязано и интегрировано в фреймворк. Когда при изменении записи ты можешь сериализовать модель и отправить её по средствам соккетов на фронт, где все изменения тут же отобразятся. Когда на определенные события ты можешь определенным образом отреагировать, к примеру отправив уведомление или письмо на создание / изменение чего-то там. Ну или логировать все изменения нужной модели. Короче, когда модель дает каркас для построения приложения вокруг данных.
     
    MouseZver и mahmuzar нравится это.
  15. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
  16. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Пока ещё не рабочего.

    1. Нужно оформить это в качестве пакета для composer
    2. Нужны тесты )
     
  17. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    I'm not a fan of composer
    --- Добавлено ---
    всмысле?
     
  18. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
    Это плохо. Тут даже дискутировать не о чем. Просто плохо.
     
  19. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    MySQLi
    PHP:
    1. <?php
    2.  
    3. class Lerma
    4. {
    5.     private static
    6.         $instance,
    7.         $mysqli = [
    8.             'host' => '127.0.0.1',
    9.             'user' => 'root',
    10.             'password' => '',
    11.             'dbname' => 'single',
    12.             'port' => 3306
    13.         ];
    14.    
    15.     protected static function instance()
    16.     {
    17.         if ( self::$instance === NULL )
    18.         {
    19.             self::$instance = self::driver();
    20.         }
    21.        
    22.         return self::$instance;
    23.     }
    24.     public static function __callStatic( $method, $args )
    25.     {
    26.         return self::instance() -> $method( ...$args );
    27.     }
    28.     protected static function driver()
    29.     {
    30.         return new class ( self::$mysqli )
    31.         {
    32.             private $connect;
    33.             private $statement;
    34.             private $result;
    35.            
    36.             public function __construct ( array $params = [] )
    37.             {
    38.                 if ( empty ( $params ) )
    39.                 {
    40.                     throw new Exception( 'Params expects most parameter values, returned empty' );
    41.                 }
    42.                
    43.                 $params = array_values ( $params );
    44.                
    45.                 $this -> connect = new mysqli( ...$params );
    46.                 $this -> connect -> set_charset( 'utf8' );
    47.                
    48.                 if ( $this -> connect -> connect_error )
    49.                 {
    50.                     throw new Exception( 'Error connect (' . $this -> connect -> connect_errno . ') ' . $this -> connect -> connect_error );
    51.                 }
    52.             }
    53.             protected function error( $obj )
    54.             {
    55.                 if ( $obj -> errno )
    56.                 {
    57.                     throw new Exception( $obj -> error );
    58.                 }
    59.             }
    60.             protected function result()
    61.             {
    62.                 if ( is_a ( $this -> statement, mysqli_stmt::class ) )
    63.                 {
    64.                     return $this -> result;
    65.                 }
    66.                
    67.                 return $this -> statement;
    68.             }
    69.             public function query( string $sql )
    70.             {
    71.                 $this -> statement = $this -> connect -> query( $sql );
    72.                 $this -> error( $this -> connect );
    73.                
    74.                 return $this;
    75.             }
    76.             public function prepare( string $sql )
    77.             {
    78.                 $this -> statement = $this -> connect -> prepare( $sql );
    79.                 $this -> error( $this -> connect );
    80.                
    81.                 return $this;
    82.             }
    83.             public function execute( array $arguments )
    84.             {
    85.                 if ( !is_a ( $this -> statement, mysqli_stmt::class ) )
    86.                 {
    87.                     throw new Exception( 'Not execute' );
    88.                 }
    89.                
    90.                 $types = array_map ( function ( $val )
    91.                 {
    92.                     if ( !in_array ( $type = gettype ( $val ), [ 'integer', 'double', 'string' ] ) )
    93.                     {
    94.                         throw new Exception( 'Invalid type ' . $type );
    95.                     }
    96.                    
    97.                     return $type{0};
    98.                 },
    99.                 $arguments );
    100.                
    101.                 $arguments = array_values ( $arguments );
    102.                
    103.                 extract ( $arguments, EXTR_PREFIX_ALL, 'bind' );
    104.                
    105.                 $a = [];
    106.                
    107.                 foreach ( $arguments AS $k => $arg )
    108.                 {
    109.                     $a[] = &${ 'bind_' . $k };
    110.                 }
    111.                
    112.                 $arguments = array_merge ( [ implode ( '', $types ) ], $a );
    113.                
    114.                 $this -> statement -> bind_param( ...$arguments );
    115.                
    116.                 $bool = $this -> statement -> execute();
    117.                 $this -> result = $this -> statement -> get_result();
    118.                
    119.                 $this -> error( $this -> statement );
    120.                
    121.                 return ( $this -> result === FALSE ? $bool : $this );
    122.             }
    123.             public function fetch( int $fetch_style = 3 )
    124.             {
    125.                 switch ( $fetch_style )
    126.                 {
    127.                     case 1:
    128.                         return $this -> result() -> fetch_array( MYSQLI_NUM );
    129.                     break;
    130.                     case 2:
    131.                         return $this -> result() -> fetch_array( MYSQLI_ASSOC );
    132.                     break;
    133.                     case 3:
    134.                         return $this -> result() -> fetch_array( MYSQLI_BOTH );
    135.                     break;
    136.                     case 4:
    137.                         return $this -> result() -> fetch_object();
    138.                     break;
    139.                     default:
    140.                         throw new Exception( 'Invalid fetch_style ' . $fetch_style . ' is not switch' );
    141.                 }
    142.             }
    143.             public function fetchAll( int $fetch_style = 3 ): array
    144.             {
    145.                 switch ( $fetch_style )
    146.                 {
    147.                     case 1:
    148.                         return $this -> result() -> fetch_all( MYSQLI_NUM );
    149.                     break;
    150.                     case 2:
    151.                         return $this -> result() -> fetch_all( MYSQLI_ASSOC );
    152.                     break;
    153.                     case 3:
    154.                         return $this -> result() -> fetch_all( MYSQLI_BOTH );
    155.                     break;
    156.                     case 4:
    157.                         $all = [];
    158.                        
    159.                         while ( $res = $this -> fetch( $fetch_style ) )
    160.                         {
    161.                             $all[] = $res;
    162.                         }
    163.                        
    164.                         return $all;
    165.                     break;
    166.                     default:
    167.                         throw new Exception( 'Invalid fetch_style ' . $fetch_style . ' is not switch' );
    168.                 }
    169.             }
    170.             public function fetchColumn()
    171.             {
    172.                 return $this -> result() -> fetch_array( MYSQLI_NUM )[0];
    173.             }
    174.             public function rowCount(): int
    175.             {
    176.                 return $this -> result() -> num_rows;
    177.             }
    178.             public function InsertId(): int
    179.             {
    180.                 return $this -> result() -> insert_id;
    181.             }
    182.             public function __call( $method, $arguments )
    183.             {
    184.                 return $this -> statement -> $method( ...$arguments );
    185.             }
    186.         };
    187.     }
    188. }
    не тестил, побыстрому накидал
     
  20. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Обновлюшка...

    PDO deprecate :eek:
    Драйвер сломал лицо с его дальнейшей поддержкой. То бишь самая большая обвертка которая в неких местах тупит.

    Также снесло ураганом константу
    FETCH_BOTH

    и доставило новые вкусняшки
    FETCH_BIND
    FETCH_COLUMN



    Итог:
    PHP:
    1. <?php
    2.  
    3. error_reporting ( E_ALL );
    4.  
    5. use Aero\Database\Lerma AS Lerma;
    6.  
    7. spl_autoload_register ( function ( $name )
    8. {
    9.     $LermaSpace = [
    10.         Aero\Configures\Lerma::class        => 'Configures\Lerma',
    11.         Aero\Database\Lerma::class            => 'Database\Lerma',
    12.         Aero\Database\Migrate::class        => 'Database\Migrate',
    13.         Aero\Interfaces\LermaDrivers::class    => 'Interfaces\Lerma\IDrivers'
    14.     ];
    15.  
    16.     include strtr ( ( $LermaSpace[$name] ?? $name ), '\\', DIRECTORY_SEPARATOR ) . '.php';
    17. } );
    18.  
    19. /*
    20.     Мульти заправка таблицы данными с n - строк
    21.  
    22.     [
    23.         [  ], - 1
    24.         [  ], - 2
    25.         ...   - n
    26.     ]
    27. */
    28. Lerma::prepare( 'INSERT INTO lerma ( name ) VALUES ( ? )', [[ 'aaaa' ], [ 'dgdf' ], [ 'awefaw' ], [ 'dszvdszfsf' ], [ 'd' ], [ 'rrrrr' ]] );
    29.  
    30. # Познаем крайний идентификатор
    31. echo Lerma::InsertID() . PHP_EOL;
    32.  
    33.  
    34.  
    35. # пакуем весь результат, запрашивая все айдишки с возвратом числовым индексом
    36. $ids = Lerma::query( 'SELECT id FROM lerma' ) -> fetchAll( Lerma::FETCH_NUM );
    37.  
    38. # Можно и фантазией пошалить
    39. $r = Lerma::prepare( [ 'SELECT name FROM %s WHERE id BETWEEN ? AND ?', 'lerma' ], [ 10,20 ] );
    40. #echo $r -> fetchColumn();
    41.  
    42.  
    43. /*
    44.     Господа: прошлый запрос завис на сервере. В результате новенького запроса, старенький уйдет на покой автоматом.
    45.  
    46.     Биндим результат напрямую с сервера
    47. */
    48. $lerma = Lerma::prepare( [ 'SELECT CONCAT ( id, " %2$X ", name ) FROM %s WHERE id BETWEEN ? AND ?', 'lerma' , 666 ], [ 1,12 ] );
    49.  
    50. while ( $concat = $lerma -> fetch( Lerma::FETCH_BIND | Lerma::FETCH_COLUMN ) )
    51. {
    52.     /* ..алилуя.. */
    53.     echo $concat . PHP_EOL;
    54. }
    55.  
    56. $a = Lerma::query( 'SELECT id FROM lerma LIMIT 5' ) -> fetchAll( Lerma::FETCH_COLUMN );
    57. $b = Lerma::query( 'SELECT id FROM lerma LIMIT 5' ) -> fetchAll( Lerma::FETCH_NUM );
    58.  
    59. var_dump($a,$b);
     
  21. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    @MouseZver респектище за проделанную работу
    в последнее время сравниваю всё с ZF
    PHP:
    1. $s = $a->query('SELECT * FROM usraccount WHERE id = ?', [5])->toArray();
     
  22. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
  23. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Новая присыпка константами!

    Расфасовка...
    fetch( int $style, $argument = null )
    1. FETCH_NUM - нумерованные индексы
    2. FETCH_ASSOC - ассоциативные индексы
    3. FETCH_OBJ - дурной класс содержащий результат строки
    4. FETCH_BIND - связь с астралом
    5. FETCH_BIND | FETCH_COLUMN - связь с астралом и вывод результата с первой колонки. Ругается (ниже).
    6. FETCH_COLUMN - выводит содержимое первой колонки. Ругается матом, если в запросе несколько колонок запрошено.
    7. FETCH_KEY_PAIR - выводит массив содержащий [ column1 => column2 ]. Так же ругается, если в запросе не две колонки.
    8. FETCH_FUNC - Бабкины семечки. Результат помещается в ваш function тесто, где происходит желаемая обработка данных.

    fetchAll( int $style, $argument = null )
    1. FETCH_NUM - ...
    2. FETCH_ASSOC - ...
    3. FETCH_OBJ - ...
    4. FETCH_COLUMN - ...
    5. FETCH_KEY_PAIR - ...
    6. FETCH_KEY_PAIR | FETCH_NAMED - Спасает перезапись одного и того же индекса. Создает массив в индексе и помещает значения у которых индексы ( column1 ) совпали.
    7. FETCH_UNIQUE - http://phpfaq.ru/pdo/fetch#FETCH_UNIQUE
    8. FETCH_GROUP - http://phpfaq.ru/pdo/fetch#FETCH_GROUP
    9. FETCH_GROUP | FETCH_COLUMN - Содержит первую колонку + группировка.
    10. FETCH_FUNC - Ванга.
    Дано в таблице:
    id - name - num
    PHP:
    1. [
    2.     1 => [ 'Aero', 111 ],
    3.     2 => [ 'Lerma', 111 ],
    4.     3 => [ 'Migrate', 111 ],
    5.     4 => [ 'Database', 111 ],
    6.     5 => [ 'Configures', 222 ],
    7.     6 => [ 'Interfaces', 333 ],
    8.     7 => [ 'LermaDrivers', 333 ],
    9. ]

    Примеры fetchAll:

    PHP:
    1. print_r ( Lerma::query( 'SELECT name FROM lerma' ) -> fetchAll( Lerma::FETCH_COLUMN ) );
    2. (
    3.     [0] => Aero
    4.     [1] => Lerma
    5.     [2] => Migrate
    6.     [3] => Database
    7.     [4] => Configures
    8.     [5] => Interfaces
    9.     [6] => LermaDrivers
    10. )
    --------------
    PHP:
    1. print_r ( Lerma::query( 'SELECT num, name FROM lerma' ) -> fetchAll( Lerma::FETCH_KEY_PAIR ) );
    2. (
    3.     [111] => Database
    4.     [222] => Configures
    5.     [333] => LermaDrivers
    6. )
    --------------
    PHP:
    1. print_r ( Lerma::query( 'SELECT num, name FROM lerma' ) -> fetchAll( Lerma::FETCH_KEY_PAIR | Lerma::FETCH_NAMED ) );
    2. (
    3.     [111] => Array
    4.         (
    5.             [0] => Aero
    6.             [1] => Lerma
    7.             [2] => Migrate
    8.             [3] => Database
    9.         )
    10.  
    11.     [222] => Configures
    12.     [333] => Array
    13.         (
    14.             [0] => Interfaces
    15.             [1] => LermaDrivers
    16.         )
    17. )
    --------------
    PHP:
    1. print_r ( Lerma::query( 'SELECT * FROM lerma' ) -> fetchAll( Lerma::FETCH_UNIQUE ) );
    2. (
    3.     [1] => Array
    4.         (
    5.             [0] => Aero
    6.             [1] => 111
    7.         )
    8.  
    9.     [2] => Array
    10.         (
    11.             [0] => Lerma
    12.             [1] => 111
    13.         )
    14.  
    15.     [3] => Array
    16.         (
    17.             [0] => Migrate
    18.             [1] => 111
    19.         )
    20.  
    21.     [4] => Array
    22.         (
    23.             [0] => Database
    24.             [1] => 111
    25.         )
    26.  
    27.     [5] => Array
    28.         (
    29.             [0] => Configures
    30.             [1] => 222
    31.         )
    32.  
    33.     [6] => Array
    34.         (
    35.             [0] => Interfaces
    36.             [1] => 333
    37.         )
    38.  
    39.     [7] => Array
    40.         (
    41.             [0] => LermaDrivers
    42.             [1] => 333
    43.         )
    44.  
    45. )
    --------------
    PHP:
    1. print_r ( Lerma::query( 'SELECT num, name FROM lerma' ) -> fetchAll( Lerma::FETCH_GROUP ) );
    2. (
    3.     [111] => Array
    4.         (
    5.             [0] => Array
    6.                 (
    7.                     [name] => Aero
    8.                 )
    9.  
    10.             [1] => Array
    11.                 (
    12.                     [name] => Lerma
    13.                 )
    14.  
    15.             [2] => Array
    16.                 (
    17.                     [name] => Migrate
    18.                 )
    19.  
    20.             [3] => Array
    21.                 (
    22.                     [name] => Database
    23.                 )
    24.  
    25.         )
    26.  
    27.     [222] => Array
    28.         (
    29.             [0] => Array
    30.                 (
    31.                     [name] => Configures
    32.                 )
    33.  
    34.         )
    35.  
    36.     [333] => Array
    37.         (
    38.             [0] => Array
    39.                 (
    40.                     [name] => Interfaces
    41.                 )
    42.  
    43.             [1] => Array
    44.                 (
    45.                     [name] => LermaDrivers
    46.                 )
    47.  
    48.         )
    49.  
    50. )
    --------------
    PHP:
    1. print_r ( Lerma::query( 'SELECT num, name FROM lerma' ) -> fetchAll( Lerma::FETCH_GROUP | Lerma::FETCH_COLUMN ) );
    2. (
    3.     [111] => Array
    4.         (
    5.             [0] => Aero
    6.             [1] => Lerma
    7.             [2] => Migrate
    8.             [3] => Database
    9.         )
    10.  
    11.     [222] => Array
    12.         (
    13.             [0] => Configures
    14.         )
    15.  
    16.     [333] => Array
    17.         (
    18.             [0] => Interfaces
    19.             [1] => LermaDrivers
    20.         )
    21.  
    22. )
    --------------
    PHP:
    1. print_r ( Lerma::query( 'SELECT num, name FROM lerma' ) -> fetchAll( Lerma::FETCH_FUNC, function ( $a,$b )
    2. {
    3.     return [ ( $a / 390 ), strtoupper ( $b ) ];
    4. } ) );
    5. (
    6.     [0] => Array
    7.         (
    8.             [0] => 0.28461538461538
    9.             [1] => AERO
    10.         )
    11.  
    12.     [1] => Array
    13.         (
    14.             [0] => 0.28461538461538
    15.             [1] => LERMA
    16.         )
    17.  
    18.     [2] => Array
    19.         (
    20.             [0] => 0.28461538461538
    21.             [1] => MIGRATE
    22.         )
    23.  
    24.     [3] => Array
    25.         (
    26.             [0] => 0.28461538461538
    27.             [1] => DATABASE
    28.         )
    29.  
    30.     [4] => Array
    31.         (
    32.             [0] => 0.56923076923077
    33.             [1] => CONFIGURES
    34.         )
    35.  
    36.     [5] => Array
    37.         (
    38.             [0] => 0.85384615384615
    39.             [1] => INTERFACES
    40.         )
    41.  
    42.     [6] => Array
    43.         (
    44.             [0] => 0.85384615384615
    45.             [1] => LERMADRIVERS
    46.         )
    47.  
    48. )
     
  24. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Некие правки...

    - Исправлена функциональность константы FETCH_UNIQUE
    Собирала в массив с нумерованными индексами остальные колонки, теперь индексы ассоциативные.
    PHP:
    1. (
    2.     [1] => Array
    3.         (
    4.             [name] => Aero
    5.             [num] => 111
    6.         )
    7. /* ... */
    8. )
    - Удален метод fetchColumn, так как есть аналог fetch( Lerma::FETCH_COLUMN )

    Добавлены следующие константы:
    1. FETCH_CLASS - записывает данные в класс, после запускается конструктор. Имя класса задается в fetch|all во втором аргументе.
    2. FETCH_CLASSTYPE - тоже самое, но название класса берется с первой колонки результата.
    примеры потом... в школу опаздываю(с)
     
  25. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.748
    Симпатии:
    1.321
    Адрес:
    Лень
    Обновляем кое что...
    PHP:
    1. Lerma::query( [ 'UPDATE lerma SET name = "%s" WHERE id = 1', quotemeta ( Aero\test\Aero::class ) ] );

    Создаем наш тестовый класс... с наследовательностью. Aero.php
    PHP:
    1. <?php
    2.  
    3. namespace Aero\test;
    4.  
    5. class Bar
    6. {
    7.    public function __construct()
    8.    {
    9.      $this -> num = $this -> num + 3;
    10.    }
    11. }
    12. class Aero extends Bar
    13. {
    14.    protected $id;
    15.  
    16.    public function __set( $name, $value )
    17.    {
    18.      $this -> $name = $value;
    19.    }
    20. }
    --- Добавлено ---
    Присваивает результат свойствам заданного класса, после запускает конструктор.
    PHP:
    1. print_r ( Lerma::query( 'SELECT name, id, num FROM lerma LIMIT 3' ) -> fetchAll( Lerma::FETCH_CLASS, Aero\test\Aero::class ) );
    Код (Text):
    1.  
    2. Array
    3. (
    4.   [0] => Aero\test\Aero Object
    5.   (
    6.   [id:protected] => 1
    7.   [name] => Aero\test\Aero
    8.   [num] => 114
    9.   )
    10.  
    11.   [1] => Aero\test\Aero Object
    12.   (
    13.   [id:protected] => 2
    14.   [name] => Lerma
    15.   [num] => 114
    16.   )
    17.  
    18.   [2] => Aero\test\Aero Object
    19.   (
    20.   [id:protected] => 3
    21.   [name] => Migrate
    22.   [num] => 114
    23.   )
    24. )
    --- Добавлено ---
    Так же но, наименование класса берется с первой колонки. С остальных присваивает свойствам результат.
    PHP:
    1. print_r ( Lerma::query( 'SELECT name, id, num FROM lerma LIMIT 1' ) -> fetchAll( Lerma::FETCH_CLASSTYPE ) );
    Код (Text):
    1.  
    2. Array
    3. (
    4.   [0] => Aero\test\Aero Object
    5.   (
    6.   [id:protected] => 1
    7.   [num] => 114
    8.   )
    9. )
    --- Добавлено ---
    Добавление Юникью константы приводит еще к записи наименования класса в индекс результата
    PHP:
    1. print_r ( Lerma::query( 'SELECT name, id, num FROM lerma LIMIT 1' ) -> fetchAll( Lerma::FETCH_CLASSTYPE | Lerma::FETCH_UNIQUE ) );
    Код (Text):
    1.  
    2. Array
    3. (
    4.   [Aero\test\Aero] => Aero\test\Aero Object
    5.   (
    6.   [id:protected] => 1
    7.   [num] => 114
    8.   )
    9. )
    --- Добавлено ---
    Если задать второй параметр true, в индекс присвоиться лишь само имя класса
    Код (Text):
    1.  
    2. Array
    3. (
    4.   [Aero] => Aero\test\Aero Object
    5.   (
    6.   [id:protected] => 1
    7.   [num] => 114
    8.   )
    9. )