Метод Laravel insert добавление записи в бд, набор команд и примеры кода


Содержание материала:

Выборка, обновление и удаление записей

Выбрать данные можно через метод DB::select() .

Параметры рекомендуется передавать через второй атрибут метода DB::select() , т.к. это позволяет избежать SQL-инъекции (исполнение стороннего SQL-кода).

Код выше заменит :category_id на переданный параметр из массива $params . При этом переданный параметр будет обработан для безопасного использования в SQL-коде.

Добавить запись можно через метод DB::table->insert() .

Если надо добавить несколько записей, то рекомендуется передавать несколько массивов в метод DB::table->insert() , т.к. в этом случае несколько записей добавятся в базу данных за один запрос.

Обновить запись можно через метод DB::table->update() .

Также можно увеличить значение поля на указанное число.

Удалить записи можно через метод DB::table()->delete() .

Если надо удалить все записи, то рекомендуется использовать метод DB::table()->truncate() , который также сбрасывает автоинкремент на ноль.

SQL-Урок 13. Добавление данных (INSERT INTO)

В предыдущих разделах мы рассматривали работу по получению данных с заранее созданных таблиц. Теперь пора разобрать, каким же образом мы можем создавать/удалять таблицы, добавлять новые записи и удалять старые. Для этих целей в SQL существуют такие операторы, как: CREATE — создает таблицу, ALTER — изменяет структуру таблицы, DROP — удаляет таблицу или поле, INSERT — добавляет данные в таблицу. Начнем знакомство с данной группой операторов из оператора INSERT.

1. Добавление целых строк

Как видно из названия, оператор INSERT используется для вставки (добавления) строк в таблицу базы данных. Добавление можно осуществить несколькими способами:

  • — добавить одну полную строку
  • — добавить часть строки
  • — добавить результаты запроса.

Итак, чтобы добавить новую строку в таблицу, нам необходимо указать название таблицы, перечислить названия колонок и указать значение для каждой колонки с помощью конструкции INSERT INTO название_таблицы (поле1, поле2 . ) VALUES (значение1, значение2 . ). Рассмотрим на примере.

INSERT INTO Sellers ( >VALUES (‘6’, ‘1st Street’, ‘Los Angeles’, ‘Harry Monroe’, ‘USA’)

Также можно изменять порядок указания названий колонок, однако одновременно нужно менять и порядок значений в параметре VALUES.

2. Добавление части строк

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

INSERT INTO Sellers ( >VALUES (‘6’, ‘Los Angeles’, ‘Harry Monroe’)

В данном примере мы не указали значение для двух столбцов Address и Country . Вы можете исключать некоторые столбцы из оператора INSERT INTO, если это позволяет производить определение таблицы. В этом случае должно соблюдаться одно из условий: этот столбец определен как допускающий значение NULL (отсутствие какого-либо значения) или в определение таблицы указанное значение по умолчанию. Это означает, что, если не указано никакое значение, будет использовано значение по умолчанию. Если вы пропускаете столбец таблицы, которая не допускает появления в своих строках значений NULL и не имеет значения, определенного для использования по умолчанию, СУБД выдаст сообщение об ошибке, и это строка не будет добавлена.

3. Добавление отобранных данных

В предыдущей примерах мы вставляли данные в таблицы, прописывая их вручную в запросе. Однако оператор INSERT INTO позволяет автоматизировать этот процесс, если мы хотим вставлять данные из другой таблицы. Для этого в SQL существует такая кострукция как INSERT INTO . SELECT . . Данная конструкция позволяет одновременно выбирать данные из одной таблицы, и вставить их в другую. Предположим мы имеем еще одну таблицу Sellers_EU с перечнем продавцов нашего товара в Европе и нам нужно их добавить в общую таблицу Sellers. Структура этих таблиц одинакова (то же количество колонок и те же их названия), однако другие данные. Для этого мы можем прописать следующий запрос:

INSERT INTO Sellers ( >SELECT >FROM Sellers_EU

Нужно обратить внимание, чтобы значение внутренних ключей не повторялись (поле ID), в противном случае произойдет ошибка. Оператор SELECT также может включать предложения WHERE для фильтрации данных. Также следует отметить, что СУБД не обращает внимания на названия колонок, которые содержатся в операторе SELECT, для нее важно только порядок их расположения. Поэтому данные в первом указанном столбце, что были выбраны из-за SELECT, будут в любом случае заполнены в первый столбец таблицы Sellers, указанной после оператора INSERT INTO, независимо от названия поля.

4. Копирование данных из одной таблицы в другую

Часто при работе с базами данных возникает необходимость в создании копий любых таблиц, с целью резервирования или модификации. Чтобы сделать полную копию таблицы в SQL предусмотрен отдельный оператор SELECT INTO. Например, нам нужно создать копию таблицы Sellers, нужно будет прописать запрос следующим образом:

SELECT * INTO Sellers_new FROM Sellers

В отличие от предыдущей конструкции INSERT INTO . SELECT . , когда данные добавляются в существующую таблицу, конструкция SELECT . INTO . FROM . копирует данные в новую таблицу. Также можно сказать, что первая конструкция импортирует данные, а вторая — экспортирует. При использовании конструкции SELECT . INTO . FROM . следует учитывать следующее:

  • — можно использовать любые предложения в операторе SELECT, такие как GROUP BY и HAVING
  • — для добавления данных из нескольких таблиц можно использовать объединение
  • — данные возможно добавить только одну таблицу, независимо от того, из скольких таблиц они были взяты.

Основные операции с данными

Добавление данных. Команда INSERT

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

После выражения INSERT INTO в скобках можно указать список столбцов через запятую, в которые надо добавлять данные, и в конце после слова VALUES скобках перечисляют добавляемые для столбцов значения.

Например, пусть в базе данных productsdb есть следующая таблица Products:

Добавим в эту таблицу одну строку с помощью следующего кода:

В данно случае значения будут передаваться столбцам по позиции. То есть стобцу ProductName передается строка «iPhone X», столбцу Manufacturer — строка «Apple» и так далее.

Важно, чтобы между значениями и типами данных столбцов было соответствие. Так, столбец ProductName представляет тип varchar , то есть строку. Соответственно этому столбцу мы можем передать строковое значение в одинарных кавычках. А стобец ProductCount представляет тип int , то есть целое число, поэтому данному столбцу нужно передать целые числа, но никак не строки.

После удачного выполнения в MySQL Workbench в поле вывода должны появиться зеленый маркер и сообщение «1 row(s) affected»:

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

Также мы можем опускать при добавлении такие столбцы, которые поддерживают значение NULL или для которых указано значение по умолчанию, то есть для них определены атрибуты NULL или DEFAULT . Так, в таблице Products столбец ProductCount имеет значение по умолчанию — число 0. Поэтому мы можем при добавлении опустить этот столбец, и ему будет передаваться число 0:

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

Множественное добавление

Также мы можем добавить сразу несколько строк:

В данном случае в таблицу будут добавлены три строки.

Вставка новых записей в базу данных Insert new records into a database

Чтобы вставить новые записи в базу данных, можно использовать метод TableAdapter.Update или один из методов DBDirect адаптера таблицы (в частности метод TableAdapter.Insert ). To insert new records into a database, you can use the TableAdapter.Update method, or one of the TableAdapter’s DBDirect methods (specifically the TableAdapter.Insert method). Дополнительные сведения см. в разделе TableAdapter. For more information, see TableAdapter.

Если приложение не использует адаптеры таблиц TableAdapter, можно использовать объекты команд (например, SqlCommand) для вставки новых записей в базу данных. If your application doesn’t use TableAdapters, you can use command objects (for example, SqlCommand) to insert new records in your database.

Если приложение использует наборы данных для хранения, используйте метод TableAdapter.Update . If your application uses datasets to store data, use the TableAdapter.Update method. Метод Update отправляет все изменения (обновления, вставки и удаления) в базу данных. The Update method sends all changes (updates, inserts, and deletes) to the database.

Если приложение использует объекты для хранения данных или требуется более точный контроль над созданием новых записей в базе данных, используйте метод TableAdapter.Insert . If your application uses objects to store data, or if you want finer control over creating new records in the database, use the TableAdapter.Insert method.

Если в TableAdapter нет метода Insert , это означает, что адаптер таблицы настроен для использования хранимых процедур или свойство GenerateDBDirectMethods имеет значение false . If your TableAdapter doesn’t have an Insert method, it means that either the TableAdapter is configured to use stored procedures or its GenerateDBDirectMethods property is set to false . Попробуйте задать для свойства GenerateDBDirectMethods TableAdapter значение true в Конструктор наборов данных, а затем сохраните набор данных. Try setting the TableAdapter’s GenerateDBDirectMethods property to true from within the Dataset Designer, and then save the dataset. Это приведет к повторному формированию TableAdapter. This will regenerate the TableAdapter. Если TableAdapter по-прежнему не содержит Insert метод, то таблица, вероятно, не предоставляет достаточно сведений о схеме для различения отдельных строк (например, в таблице может отсутствовать набор первичных ключей). If the TableAdapter still doesn’t have an Insert method, the table probably does not provide enough schema information to distinguish between individual rows (for example, there might be no primary key set on the table).

Вставка новых записей с помощью адаптеров таблиц Insert new records by using TableAdapters

Адаптеры таблиц предоставляют различные способы вставки новых записей в базу данных в зависимости от требований приложения. TableAdapters provide different ways to insert new records into a database, depending on the requirements of your application.

Если приложение использует наборы данных для хранения, можно просто добавить новые записи в нужные DataTable в наборе данных, а затем вызвать метод TableAdapter.Update . If your application uses datasets to store data, you can simply add new records to the desired DataTable in the dataset, and then call the TableAdapter.Update method. Метод TableAdapter.Update отправляет любые изменения в DataTable в базу данных (включая измененные и удаленные записи). The TableAdapter.Update method sends any changes in the DataTable to the database (including modified and deleted records).

Вставка новых записей в базу данных с помощью метода TableAdapter. Update To insert new records into a database by using the TableAdapter.Update method

Добавьте новые записи в нужные DataTable, создав новый DataRow и добавив их в коллекцию Rows. Add new records to the desired DataTable by creating a new DataRow and adding it to the Rows collection.

После добавления новых строк в DataTable вызовите метод TableAdapter.Update . After the new rows are added to the DataTable, call the TableAdapter.Update method. Объем обновляемых данных можно контролировать путем передачи всего DataSet, DataTable, массива DataRows или одного DataRow. You can control the amount of data to update by passing in either an entire DataSet, a DataTable, an array of DataRows, or a single DataRow.

В следующем коде показано, как добавить новую запись в DataTable и затем вызвать метод TableAdapter.Update , чтобы сохранить новую строку в базе данных. The following code shows how to add a new record to a DataTable and then call the TableAdapter.Update method to save the new row to the database. (В этом примере используется таблица Region в базе данных Northwind.) (This example uses the Region table in the Northwind database.)

Вставка новых записей в базу данных с помощью метода TableAdapter. INSERT To insert new records into a database by using the TableAdapter.Insert method

Если приложение использует объекты для хранения данных, можно использовать метод TableAdapter.Insert для создания новых строк непосредственно в базе данных. If your application uses objects to store data, you can use the TableAdapter.Insert method to create new rows directly in the database. Метод Insert принимает отдельные значения для каждого столбца в качестве параметров. The Insert method accepts the individual values for each column as parameters. При вызове метода в базу данных вставляется новая запись с передаваемыми значениями параметров. Calling the method inserts a new record into the database with the parameter values passed in.

  • Вызовите метод Insert TableAdapter, передав значения для каждого столбца в качестве параметров. Call the TableAdapter’s Insert method, passing in the values for each column as parameters.

В следующей процедуре показано использование метода TableAdapter.Insert для вставки строк. The following procedure demonstrates using the TableAdapter.Insert method to insert rows. В этом примере данные вставляются в таблицу Region базы данных Northwind. This example inserts data into the Region table in the Northwind database.

Если у вас нет доступного экземпляра, создайте экземпляр TableAdapter, который вы хотите использовать. If you do not have an instance available, instantiate the TableAdapter you want to use.

Вставка новых записей с помощью командных объектов Insert new records by using command objects

Новые записи можно вставлять непосредственно в базу данных с помощью командных объектов. You can insert new records directly into a database using command objects.

Вставка новых записей в базу данных с помощью командных объектов To insert new records into a database by using command objects

  • Создайте новый объект Command, а затем задайте его свойства Connection , CommandType и CommandText . Create a new command object, and then set its Connection , CommandType , and CommandText properties.

В следующем примере демонстрируется вставка записей в базу данных с помощью командного объекта. The following example demonstrates inserting records into a database using command object. Данные вставляются в таблицу Region базы данных Northwind. It inserts data into the Region table in the Northwind database.

Безопасность в .NET .NET security

Необходимо иметь доступ к базе данных, к которой вы пытаетесь подключиться, а также разрешение на выполнение вставки в нужную таблицу. You must have access to the database you are trying to connect to, as well as permission to perform inserts into the desired table.

12 основных примеров команды INSERT в MySQL

Главное меню » Базы данных » База данных MySQL » 12 основных примеров команды INSERT в MySQL

В этом руководстве объясняется, как использовать команду INSERT в MySQL и несколько практических и полезных примеров.

Топ-пост этого месяца:  Проблема с All in One SEO Pack и ее решение — убираем rel=prev и исправляем rel=canonical, чтобы

Рассматриваются в данном руководстве следующие примеры:

  1. Основные примеры команды Insert
  2. Вставьте значения только для выбранных столбцов
  3. Пример INSERT с SET
  4. Вставка записей на основе строк из другой таблицы
  5. Вставка значений выбранных столбцов из другой таблицы
  6. Вставить записи в определенный раздел
  7. Вставка записи в несколько разделов в таблице
  8. Игнорировать сообщение об ошибке во время ввода текста
  9. Значения по умолчанию в Insert
  10. Экспрессия в вставки значений
  11. Сделайте приоритет команды Insert ниже или выше
  12. При найденном дубликате, обновить значение столбца

В следующем примере мы подключимся к базу данных andreyexbase с именем пользователя devuser и паролем mysecretpwd

Для этого урока мы вставим значения в таблице сотрудников. Это структура таблицы сотрудников.

Если вы новичок в MySQL, используйте это Как создать MySQL базу данных и таблицу, чтобы начать работу.

1. Основные примеры команды Insert

Следующая команда вставит три новых записей в таблице сотрудников. В этом примере, после “values”, укажет значения для всех столбцов в таблице.

С помощью команды SELECT в MySQL, убедитесь, что записи был успешно установлены.

2. Вставьте значения только для выбранных столбцов

Если вы хотите, вставить значения только выбранных столбцов, следует указать имена столбцов в команде вставки.

Ниже будет вставлены две записи только для столбцов идентификатора и имени.

Для “отдела” и столбца “зарплаты”, мы не указали никаких значений для этой конкретной записи. Таким образом, мы будем видеть NULL в качестве значения в нашем выводе команды SELECT. Обратите внимание, что это не строка “NULL”, именно значение столбца в строке действительно нулевая.

3. Пример INSERT с SET

Вместо того чтобы использовать ключевого слова “values” в вашей команде выбора, вы можете также использовать ключевое слово “set” в вашей команде выбора, как показано ниже.

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

4. Вставка записей на основе строк из другой таблицы

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

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

Вы можете также использовать различные условия в “where” выберите команду, чтобы выбрать записи из таблицы подрядной и вставить в таблицу служащих, как показано ниже.

Примечание: Если вы привыкли к базе данных Oracle, вы будете использовать “insert into worker AS select * from contractor”. Обратите внимание, что MySQL не использует ключевого слова “AS” в данном контексте.

5. Вставка значений выбранных столбцов из другой таблицы

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

В следующем примере будет принимать значения “ID” и “name” для всех строк в таблице подрядчика и вставлять его в таблицу сотрудников.

Так же, как и в предыдущем примере, вы можете также использовать, когда есть условие и ограничение на записи.

Обратите внимание, что если запись уже существует для первичного ключа (что идентификатор) в таблице сотрудников, вы получите следующее сообщение об ошибке. Следующее сообщение об ошибке указывает на то, что идентификационный номер сотрудника “100” уже существует в таблице сотрудников.

6. Вставить записи в определенный раздел

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

В следующем примере будет вставлять записи в таблицу служащих в разделе p1

Обратите внимание, что строка уже существует в данном конкретном разделе. Например, в данном примере p1, вы получите следующее сообщение об ошибке:

Примечание: Эта функция будет работать только на MySQL 5.6 и выше.

7. Вставка записи в несколько разделов в таблице

Вы также можете вставлять записи на несколько разделов с помощью одного оператора вставки.

Следующий оператор вставки вставляет запись с идентификатором “100” в разделе p1, и запись с идентификатором “200” в разделе p2.

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

Опять же, это будет работать только на MySQL 5.6 и выше.

8. Игнорировать сообщение об ошибке во время ввода текста

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

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

Чтобы проигнорировать выше сообщение об ошибке, вы можете использовать “insert ignore” (вместо того, чтобы просто вставить), как показано ниже. Обратите внимание, что это еще не вставит запись в таблицу, поскольку есть primary key в идентификаторе столбца. Но, это просто игнорирует сообщение об ошибке.

9. Значения по умолчанию в Insert

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

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

Например, в бонусной таблице, оба значения столбца установлены в положение “not null”.

Давайте вставим запись в эту таблицу для столбца идентификаторов.

Когда вы выполните команду select, вы заметите, что колонка “сумма” автоматически устанавливается неявной значением 0 по умолчанию.

Если вы не указываете как для идентификатора и суммы, будет установлено на 0 автоматически, как показано ниже. Если значения не заданы, то MySQL будет использовать значения по умолчанию.

Примечание: Вы можете также использовать ключевое слово “DEFAULT” в значениях, как показано ниже, что позволит достичь выхода, как описано выше.

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

10. Экспрессия в вставки значений

В следующем примере для значения бонуса, мы определили “5000 + идентификатор” в качестве значения. Таким образом, это добавит значение идентификатор служащего к значению бонуса и вставит окончательное значение в колонке бонуса, как показано ниже.

Вы можете использовать “+”, “-“, “*”, или любой другой действующий оператор выражения MySQL в значениях. В следующем примере, он использует “50 * 2” для столбца идентификаторов. Таким образом, идентификатор, который будет вставлен в “100”

Вы можете также обратиться к значениям других столбцов. В следующем примере, он использует “5000 + id” для бонусного столбца. Таким образом, это будет иметь значение столбца идентификаторов (который является 100), и добавить его к 5000. Таким образом, окончательное значение бонуса “5100”, как показано ниже.

11. Сделайте приоритет команды Insert ниже или выше

Для движка, которая поддерживает блокировку таблицы (например, MyISAM), вы можете указать приоритет вашей вставки.

Например, эта команда Insert будет задерживать вставку (сделать его низкий приоритет) до тех пор, никто ни кто не будет читать таблицу.

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

Пожалуйста, имейте в виду, что если ваша база данных интенсивно считывается и если вы укажете LOW_PRIORITY в команде Insert, то ваша вставка может длится в течение очень долгого времени.

Кроме того, обратите внимание, что это немного отличается от “INSERT … DELAYED”, который является устаревшим, начиная с MySQL 5.6.6. Таким образом, не следует больше использовать “insert … delayed”.

12. При найденном дубликате, обновить значение столбца

Во время вставки, если есть дубликат ключа, она не будет выполнена, как показано ниже, в качестве идентификатора “100” уже существует в таблице.

Тем не менее, вы можете сделать некоторые обновления для этой конкретной записи (если дубликат обнаружен) с помощью “ON DUPLICATE KEY UPDATE”, как показано ниже.

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

Обратите внимание, что в приведенном выше примере, при вставке, даже если обновляется только одна запись, то выход будет такой: “2 rows affected”.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Все о WEB программировании

WEB программирование от А до Я

Заказать сайт:

Социальные сети:

Партнеры:

Laravel: как скопировать строку из таблицы используя Eloquent

Доброго времени суток. Это статья из серии фишки Laravel. Так в одной из статей «Установки значения столбцов базы данных по умолчанию в Laravel» мы рассмотрели, как установить дефолтные значения столбцов базы данных. А в этой статье рассмотрим, как скопировать строку из таблицы используя Eloquent.

Вводные данные у нас есть таблица orders, которая имеет следующую структуру.

Есть модель Order

И настроено подключение к базе данных в .env.

Давайте создадим контроллер, который будет иметь три метода:

  • Добавлять запись
  • Выводить все записи
  • И копировать запись

Создание контроллера в Laravel

Для создания контроллера используем команду artisan

Таким образом мы с вами создали контроллер OrderController с прписанными методами:

  • index()
  • create()
  • store(Request $request)
  • show($id)
  • edit($id)
  • update(Request $request, $id)
  • destroy($id)

Нам осталось только прописать действия в методах

Создание метода для добавления записей

Для добавления новой записи у нас будут использоваться два метода create, который будет выводить форму добавления и store, который будет добавлять запись в базу данных.

Опишем метод create

Метод просто возвращает вьюшку create.blade.php

Теперь давайте опишем метод store, который получает данные методом POST и записывет их в базу.


Вызываем статический метод create модели Order, который записывает в таблицу orders данные.

И дальше возвращаем редирект обратно откуда мы пришли, добавляя флеш сообщение «Данные сохранены»

Что такое флеш сообщение вы можете прочитать в документации Laravel

Создание view для добавления данных в Laravel

Создаем файл create.blade.php в resources/views и добавляем в него следующий код.

Тут тоже ничего сложного нет. С помощью строки
подключаем bootstrap. Дальше проверяем сессию message, которую мы передаем как флеш сообщение. Если она существует выводим ее содержимое.

Дальше создаем форму, где в качестве параметра action передаем роут с названием store.

Дальше используем хелпер csrf_field(), который в нашу форму помещает с токеном, необходимо для защиты от межсайтовых запросов.

Ну в принципе и все. Осталось создать два роута. Открываем файл web.php, который находится в папке routes. И добавляем два именованных роута:

Теперь можем проверить и добавить несколько значений.

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

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

Создание метода для вывода данных

Для вывода всех данных будем использовать метод index контроллера OrderController. Давайте опишем его:

В данном методе мы используем статический метод all() модели Order, который возвращает нам все данные из таблицы. И дальше возвращаем вьюшку index.blade.php, в которую передаем массив данных.

Создание view для отображения всех данных в Laravel

Создаем файл index.blade.php в каталоге resources/views

Тут ничего сложного нет. Перебираем массив $orders и выводим его значения. Единственное в ссылке «Скопировать» мы не указали адрес. Это мы сделаем чуть позже.

Осталось только добавить роут в файл routes/web.php

Отлично, все работает.

Теперь переходим к самому интересному. Создаем метод для копирования строки.

Создание метода копирования строки в Laravel

Создадим метод copy в контроллере OrderController и опишем его.

Первое мы получаем заказ по его id, используя метод find. Дальше используя метод replicate копируем данные и сохраняем их.

Отлично, теперь добавим роут.

Изменим немного файл index.blade.php. Добавим к ссылке адрес:

Теперь можно проверить. Напротив данных, жмем «Копировать» и у нас появляется новая запись с тем же именем.

Отлично. Все работает.

Заключение.

Для копирования данных из таблицы с помощью Eloquent в Laravel существует метод replicate(), который копирует данные.

20 хитростей в Laravel Eloquent о которых вы не знали

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

1. Инкременты и Декременты

$article = Article::find($article_id);
$article->read_count++;
$article->save();

Вы можете делать так:

$article = Article::find($article_id);
$article->increment(‘read_count’);

Article::find($article_id)->increment(‘read_count’);
Article::find($article_id)->increment(‘read_count’, 10); // +10
Product::find($produce_id)->decrement(‘stock’); // -1

2. XorY методы

В Eloquent существует несколько методов которые можно объеденять в один, что-то вроде «Сделай Х, и в случае неудачи сделай Y».

Пример 1: findOrFail():

$user = User::find($id); if (!$user)

Вы можете делать так:

Пример 2: findOrCreate():

Вместо вот такого:

$user = User::where(’email’, $email)->first();
if (!$user) <
User::create([
’email’ => $email
]);
>

Лучше делать вот так:

$user = User::firstOrCreate([’email’ => $email]);

3. Метод boot()

В методе boot() вы можете переопределить поведение Eloquent модели:

class User extends Model
<
public static function boot()
<
parent::boot();
static::updating(function($model)
<
// do some logging
// override some property like $model->something = transform($something);
>);
>
>

Самым распростронненным примером использования метода boot() — установка значения по-умолчанию для какого-либо поля. Например, сгенерируем UUID в момент создания модели:

public static function boot()
<
parent::boot();
self::creating(function ($model) <
$model->uu > >);
>

4. Relationship с условиями и сортировкой

Вот так обычно определяют отношения:

public function users() <
return $this->hasMany(‘App\User’);
>

Но знали ли вы, что уже на данном этапе можно добавить orderBy? Например, если мы хотим добавить relation только для определенного типа пользователей, с сортировкой по email, то мы можем сделать так:

public function approvedUsers() <
return $this->hasMany(‘App\User’)->where(‘approved’, 1)->orderBy(’email’);
>

5. Свойства модели: timestmap, appends, и т.д.

В Eloquent модели имеется несколько свойств, о которых многие не знают. Самые популярные:

class User extends Model <
protected $table = ‘users’;
protected $fillable = [’email’, ‘password’]; // which fields can be filled with User::create()
protected $dates = [‘created_at’, ‘deleted_at’]; // which fields will be Carbon-ized
protected $appends = [‘field1’, ‘field2’]; // additional values returned in JSON
>

Но существуют и другие, такие как:

protected $primaryKey = ‘uuid’; // Если у вас нету поля ‘id’
public $incrementing = false; // Указывает что primary key не имеет свойства auto increment
protected $perPage = 25; // А тут мы переопределяем кол-во результатов на странице при пагинации (по-умолчанию: 15)
const CREATED_AT = ‘created_at’; const UPDATED_AT = ‘updated_at’; // А этими константами можно переопределить название полей для created_at и updated_at
public $timestamps = false; // или можно указать что мы вообще не используем поля created_at и updated_at

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

6. Поиск нескольких записей

Все знают про метод find(), верно?

Но я был удивлен, что очень немногие знают что этот метод принимает так же массив с несколькими ключами:

7. WhereX

В Eloquent существует элегантный способ превратить это:

$users = User::where(‘approved’, 1)->get();

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

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

User::whereDate(‘created_at’, date(‘Y-m-d’));
User::whereDay(‘created_at’, date(‘d’));
User::whereMonth(‘created_at’, date(‘m’));
User::whereYear(‘created_at’, date(‘Y’));

8. Сортировка по relation

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

Для начала мы пропишем отдельную связь latest post в модели темы:

public function latestPost()
<
return $this->hasOne(\App\Post::class)->latest();
>

И затем, в нашем контроллере, мы можем творить магию:

9. Eloquent::when() — избавляется от if-else

Многие из нас пишут подобные условные конструкции:

if (request(‘filter_by’) == ‘likes’) <
$query->where(‘likes’, ‘>’, request(‘likes_amount’, 0));
>
if (request(‘filter_by’) == ‘date’) <
$query->orderBy(‘created_at’, request(‘ordering_rule’, ‘desc’));
>

Но есть более изящный способ это сделать:

$query = Author::query();
$query->when(request(‘filter_by’) == ‘likes’, function ($q) <
return $q->where(‘likes’, ‘>’, request(‘likes_amount’, 0));
>);
$query->when(request(‘filter_by’) == ‘date’, function ($q) <
return $q->orderBy(‘created_at’, request(‘ordering_rule’, ‘desc’));
>);

10. BelongsTo и Модель по-умолчанию

Представим что у нас есть модель Post, которая belongsTo к модели Author, и мы выводим автора в шаблоне:

Но что случится если модель автора удалена или null по какой-нибудь причине? Будет ошибка! Конечно мы может сделать проверку:

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

public function author()
<
return $this->belongsTo(‘App\Author’)->withDefault();
>

В данном примере relation author() вернет пустую модель Author, если в Post нету связи с реальной моделью. Мы можем даже указать свойства по-умолчанию для этой пустой модели:

public function author()
<
return $this->belongsTo(‘App\Author’)->withDefault([
‘name’ => ‘Guest Author’
]);
>

11. Order by Mutator

Представим что у нас есть такой код:

function getFullNameAttribute()
<
return $this->attributes[‘first_name’] . ‘ ‘ . $this->attributes[‘last_name’];
>

Вы хотите сделать сортировку по full_name? Такой подход не сработает:

$clients = Client::orderBy(‘full_name’)->get(); // так не работает

Решение довольно простое. Мы должны сортировать результаты ПОСЛЕ того как мы их получили:

$clients = Client::get()->sortBy(‘full_name’); // а вот так работает!

Обратите внимание что мы используем не orderBy, а sortBy, функцию из Collection .

12. Сортировка по-умолчанию для глобального scope

Что если мы хотим, чтобы запрос User::all() всегда был отсортирован по полю name ? Мы можем назначить глобальный scope для определения такого поведения. Давайте вернемся к методу boot(), о котором мы говорили ранее, и используем его:

protected static function boot()
<
parent::boot();

// Order by name ASC
static::addGlobalScope(‘order’, function (Builder $builder) <
$builder->orderBy(‘name’, ‘asc’);
>);
>

Подробнее можно почитать в документации.

13. Raw запросы

Иногда нам нужно осуществлять «сырые» (raw) запросы к базе данных. К счастью Eloquent поддерживает и их:

// whereRaw
$orders = DB::table(‘orders’)
->whereRaw(‘price > IF(state = «TX», ?, 100)’, [200])
->get();

// havingRaw
Product::groupBy(‘category_id’)->havingRaw(‘COUNT(*) > 1’)->get();

// orderByRaw
User::where(‘created_at’, ‘>’, ‘2020-01-01’)
->orderByRaw(‘(updated_at — created_at) desc’)
->get();

14. Replicate: создать копию записи

Очень коротко: вот так можно создать копию записи в базе данных:

$task = Tasks::find(1);
$newTask = $task->replicate();
$newTask->save();

15. Метод Chunk для больших таблиц

Это больше относится к коллекциям, а не к Eloquent, но все равно. Если у вас есть большая таблица (с тысячами записей) и вы не можете получить их все за один запрос, то можно использовать метод chunk , который будет доставать записи по «чуть-чуть»:

Топ-пост этого месяца:  Статус Мало показов в Яндекс.Директ почему появился, что делать

User::chunk(100, function ($users) <
foreach ($users as $user) <
// .
>
>);

16. Создаем дополнительные вещи при создании модели

Все мы знаем про команду php artisan make:model Company . Но знали ли вы, что вы сразу можете сгенерировать: миграцию, контроллер, и даже указать что контроллер должен быть REST? Используя дополнительные флаги мы можем сделать это одной командой:

php artisan make:model Company -mcr

Где флаги означают:

  • m — создать файл миграции
  • c — создать контроллер
  • r — контроллер должен быть REST

17. Не обновлять update_at при сохранении

Зналил ли вы, что метод ->save() принимает дополнительные параметры? Например, мы можем указать что не нужно обновлять timestamps, если нам это не нужно:

$product = Product::find($id);
$product->updated_at = ‘2020-01-01 10:00:00’;
$product->save([‘timestamps’ => false]);

Такой код не будет обновлять update_at при вызове save() .

18. Узнать результат update()

Задавались ли вы когда-нибудь вопросом что возвращает такой код:

$result = $products->whereNull(‘category_id’)->update([‘category_id’ => 2]);

Я имею ввиду не что конкретно делает метод update() , а что в результате будет в переменной $result ?

Ответ: кол-во затронутых строк! Так что если вы захотите узнать сколько строк обновил ваш вызов update() — вам не требуется ничего делать! Вы можете просто посмотреть на значение которое он вернул.

19. Преобразование скобочек из SQL в Eloquent запрос

Что если у вас имеется подобный SQL запрос:

. WHERE (gender = ‘Male’ and age >= 18) or (gender = ‘Female’ and age >= 65)

Как правильно составить Eloquent запрос для него? Вот так неправильно:

$q->where(‘gender’, ‘Male’); $q->orWhere(‘age’, ‘>=’, 18);
$q->where(‘gender’, ‘Female’);
$q->orWhere(‘age’, ‘>=’, 65);

У вас получится неправильный SQL запрос. Правильный способ чуть более сложный, и заключается в использовании замыканий:

$q->where(function ($query) <
$query->where(‘gender’, ‘Male’)
->where(‘age’, ‘>=’, 18);
>)->orWhere(function($query) <
$query->where(‘gender’, ‘Female’)
->where(‘age’, ‘>=’, 65);
>)

20. orWhere с несколькими параметрами

В завершение: вы можете передавать массив параметров в orWhere() метод. Обычно делают так:

Вы же можете быть более крутыми, и делать вот так:

Я уверен что существует еще множется трюков, о которых мы не знаем. Возможно кто-то поделится ими в комментариях.

Метод Laravel insert: добавление записи в бд, набор команд и примеры кода

Следующая команда соединит нас с БД devdb , имя пользователя devuser и пароль mysecretpwd .

Мы будем вводить данные в таблицу employee . Структура таблицы приведена ниже:

Пример базового использования команды INSERT

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

Используйте команду SELECT для проверки введенных данных.

Вставка данных только для определенных столбцов

Если вы хотите вставить данные только в несколько столбцов, то их следует перечислить. Следующая команда вставит значения только в столбцы id и name .

Мы не указали значения полей dept и salary. В итоге, мы получили NULL в этих столбцах. Обратите внимание, это не строковое значение “NULL”, это значение, указывающие на то, что ячейка пуста.

Пример Insert Set

Вместо ключевого слова values вы можете использовать слово SET для установки значения нужному полю.

Следующая команда является полным аналогом той, что мы рассмотрели выше:

Вставка значений на основе значений из другой таблицы

В этом примере мы используем INSERT. SELECT метод, для выбора значений из другой таблицы.

Следующая команда копирует значения из таблицы contractor в employee .

Также вы можете комбинировать условия WHERE , для выбора определенных полей.

Внимание: Если вы работаете с БД Oracle, то используйте синтаксис insert into employee AS select * from contractor . MySQL не поддерживает ключевого слова AS в данном контексте.

Ввод выбранных столбцов из другой таблицы

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

Следующая команда выбирает поля id и name всех записей из таблицы contractor и вводит их в таблицу employee .

Также допускается использование условий WHERE.

Обратите внимание, если запись с указанным ID уже существует, вы получит ошибку. ERROR 1062 (23000): Duplicate entry ‘100’ for key ‘PRIMARY’

Ввод записей в определенную секцию

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

В следующем примере данные вводятся в раздел p1 .

Обратите внимание, что запись с этим ID уже существует в указанном разделе. Поэтому мы получим соответствующую ошибку.


Внимание: Этот пример отработает только в MySQL 5.6 и выше.

Вставка записей в несколько разделов таблицы

Вы можете при помощи одной команды вставить записи сразу в несколько разделов таблицы. Следующий запрос вставит данные в разделы p1 и p2 .

Обратите внимание, если по какой-либо причине одна из записей вызовет ошибку при обработке, то весь запрос будет отменен.

Снова, пример отработает только в MySQL 5.6 и выше.

Игнорирование ошибок при вводе данных

Если по каким-либо причинам вам необходимо пропускать ошибки при вводе данных, то вы можете использовать ключевое слово IGNORE .

К примеру, следующая команда вызовет ошибку, так как запись с таким ID уже существует.

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

Значение по-умолчанию

Если MySQL запущен в строгом режиме, то, не указав значения по-умолчанию для полей, мы получим ошибки.

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

Например, в таблице bonus оба поля не могут принимать значение NULL.

Введем значение только для id.

При выборке данных, мы видим, что поле amount приняло значение 0.

Если мы опустим оба поля при вводе данных, то они примут значение 0. Если поля не указаны при вводе, то они принимают значения по-умолчанию для таблицы.

Внимание: допускается применения ключевого слова DEFAULT . Результат выполнения запроса идентичен предыдущему.

Для строковых полей значение по-умолчанию — пустая строка. Обратите внимание, что для полей AUTO_INCREMENT значение по-умолчанию — увеличенное на единицу значение предыдущей записи.

Выражения в качестве значение в INSERT

В следующем примере, в качестве значения поля bonus мы указали 5000+id . В результате поле bonus будет равно сумме размера бонуса и ID .

Допускается использование + , — , * , или любого другого корректного оператора MySQL. В следующем примере используется 50*2 в качестве значения ID. В итоге ID примет значение 100 .

Вы также можете обращаться к значения других столбцов. Например, 5000+id для поля bonus . То есть мы используем значение столбца id (100) и добавляем его к 5000. Результирующее значение — 5100.

Изменение приоритета команды INSERT

При работе с движками, допускающими блокирование таблиц (MyISAM), допускается указывать приоритет команде INSERT .

Например, следующая команда откладывает операцию INSERT до тех пор, пока сервер не обработает все операции чтения над таблицей.

Также можно указывать высокий приоритет. Это операции полностью противоположна предыдущей.

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

Обратите внимание, что команда очень похожа на INSERT. DELAY , которая считается устаревшей начиная с MySQL версии 5.6.6, поэтому стоит избегать её использования.

Обновления строки при повторении

Если в процессе записи будет обнаружена запись с повторяющимся значением ID, операция будет остановлена с соответствующей ошибкой.

Но, вы можете обновить поля такой записи (при обнаружении дубликата) при помощи команды ON DUPLICATE KEY UPDATE .

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

Обратите внимание, что, хотя в предыдущем примере мы добавляем только одну строку, мы все равно получаем в ответ 2 rows affected .

Метод Laravel insert: добавление записи в бд, набор команд и примеры кода

Для начала установим копию Laravel на нужный сервер, как это делается можно почитать и посмотреть на разных сайтах, в том числе и на англоязычном сайте разработчиков, в разделе документации. Кстати, они там добавили два туториала по созданию to-do списка, один попроще, другой посложнее. Раньше этого не было, и была только одна документация. Я думаю, что они сделали правильно, что добавили эти два примера законченных приложений. Потому что когда в первый раз сталкиваешься с фреймворком, и тем более с достаточно многофункциональным, таким как Laravel, трудно сразу понять, как же это все вместе работает. Если вы не очень хорошо знаете английский, то перевод документации и материалов по созданию to-do списка можно найти на русскоязычных сайтах.

Пока набирал этот материал, Laravel обновили до версии 5.3 и обучающие материалы по созданию to-do списка из документации для этой версии убрали, поэтому, если что смотрите их для версии 5.2.

После того как вы установили папку с проектом нужно подкорректировать файл .env, который находится в корне. Для отработки материала из этой статьи нужно лишь настроить соединение с БД (тип БД, имя БД, пользователь, пароль). Я использую MySql.

Далее, нам нужно создать таблицы в БД. Делается это с помощью файлов миграций. В этих файлах вы описываете структуру будущих таблиц, после чего по одной команде в консоли Laravel за вас создает эти таблицы. Плюс этих файлов в том, что если вам потребуется многократно создавать таблицы, вам останется только каждый раз набирать одну команду. Это удобно, но удобство на этом не заканчивается. Вот, для примера, участок кода из файла миграции: Думаю, тут наглядно понятно, из каких столбцов ваша таблица будет состоять. Файлы миграций находятся в папке (database → migrations). Подробнее, о том, как создаются файлы миграций можно почитать в документации. По умолчанию, в папке migrations уже есть два файла: create_users_table.php и create_password_resets_table.php. В этом материале я буду использовать первый из них. Создавать дополнительных файлов миграций нам сегодня не потребуется.

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

После этого таблицы нужно наполнить содержимым. Первый способ – это seeding. Находите файл DatabaseSeeder.php (database → seeds), указываете данные, которыми вы хотите наполнить таблицы и в консоли пишете следующую команду: После чего таблицы будут заполнены нужными вам данными. Можно добавить свои данные или использовать faker. Подробнее читайте в документации.

Но материал этот посвящен не сидингу и миграциям, а тому, что появилось в версии 5.1 – это factories. Эти самые factories или фабрики можно найти в папке database → factories. Естественно, например, в четвертой версии фреймворка этой папки не было. Кстати, разработчики основательно перетряхнули папку app. Например, те же миграции и сидинги находились в папке database, которая в свою очередь находилась в папке app. Теперь папку database вынесли из папки app в корневую папку проекта. Папка controllers перекочевала в папку Http (внутри папки app). Папку models вообще убрали. И много чего еще в папке app появилось нового. После четвертой версии приходится привыкать к новой структуре папок. Но наглядно видно, что фреймворк не стоит на месте, а активно равивается.

Вернемся к фабрикам. Напоминаю, что фабрики можно найти в папке database → factories. Там вы найдете файл ModelFactory.php. По умолчанию в этом файле следующее содержимое: Здесь мы можем определить какие столбцы таблицы, и какими данными нужно заполнять.

Возвращаемся в командную строку. Создадим вручную, например, 5 пользователей. Строки таблицы для каждого пользователя будут заполнены случайными данными (так как это определено в фале ModelFactory.php). Для этого используем tinker.

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

Создание web приложения на PHP с иcпользованием Firebird и Laravel

В прошлой статье я рассказывал о пакете для поддержки СУБД Firebird в фреймворке Laravel. На этот раз мы рассмотрим процесс создания web приложения с использованием СУБД Firebird на языке PHP с использованием Laravel.

Обзор драйверов для работы с Firebird

Обзор расширения Firebird/Interbase

Расширение Firebird/Interbase появилось раньше и является наиболее проверенным. Для установки расширения Firebird/Interbase в конфигурационном файле php.ini необходимо раскомментировать строку

или для UNIX подобных систем строку

Это расширение требует, чтобы у вас была установлена клиентская библиотека fbclient.dll/gds32.dll (для UNIX подобных систем fbclient.so) соответствующей разрядности.

Замечание для пользователей Win32/Win64

Для работы этого расширения системной переменной Windows PATH должны быть доступны DLL-файлы fbclient.dll или gds32.dll. Хотя копирование DLL-файлов из директории PHP в системную папку Windows также решает проблему (потому что системная директория по умолчанию находится в переменной PATH), это не рекомендуется. Этому расширению требуются следующие файлы в переменной PATH: fbclient.dll или gds32.dll.

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

Это расширение использует процедурный подход к написанию программ. Функции с префиксом ibase_ могут возвращать или принимать в качестве одного из параметров идентификатор соединения, транзакции, подготовленного запроса или курсора (результат SELECT запроса). Этот идентификатор имеет тип resource. Все выделенные ресурсы необходимо освобождать, как только они больше не требуются. Я не буду описывать каждую из функций подробно, вы можете посмотреть их описание по ссылке, вместо этого приведу несколько небольших примеров с комментариями.

Вместо функции ibase_connect вы можете применять функцию ibase_pconnect, которая создаёт так называемые постоянные соединения. В этом случае при вызове ibase_close соединение не закрывается, все связанные с ней ресурсы освобождаются, транзакция по умолчанию подтверждается, другие виды транзакций откатываются. Такое соединение может быть использовано повторно в другой сессии, если параметры подключения совпадают. В некоторых случаях постоянные соединения могут значительно повысить эффективность вашего веб приложения. Это особенно заметно, если затраты на установку соединения велики. Они позволяют дочернему процессу на протяжении всего жизненного цикла использовать одно и то же соединение вместо того, чтобы создавать его при обработке каждой страницы, которая взаимодействует с SQL-сервером. Этим постоянные соединения напоминают работу с пулом соединений. Подробнее о постоянных соединениях вы может прочитать по ссылке.

Внимание!

Многие ibase функции позволяют не передавать в них идентификатор соединения (транзакции, подготовленного запроса). В этом случае эти функции используют идентификатор последнего установленного соединения (начатой транзакции). Я не рекомендую так делать, в особенности, если ваше веб приложение может использовать более одного подключения.

Функция ibase_query выполняет SQL запрос и возвращает идентификатор результата или true, если запрос не возвращает набор данных. Эта функция помимо идентификатора подключения (транзакции) и текста SQL запроса может принимать переменное число аргументов в качестве значений параметров SQL запроса. В этом случае наш пример выглядит следующим образом:

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

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

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

Расширение Firebird/Interbase не работает с именованными параметрами запроса.

По умолчанию расширение Firebird/Interbase автоматически стартует транзакцию по умолчанию после подключения. Транзакцию по умолчанию подтверждается при закрытии соединения функцией ibase_close. Её можно подтвердить или откатить раньше, если вызвать методы ibase_commit или ibase_rollback передав в них идентификатор соединения, или не передавая ни чего (если вы используете единственное соединение.)

Если вам необходимо явное управление транзакциями, то необходимо стартовать транзакцию с помощью функции ibase_trans. Если параметры транзакции не указаны, то транзакция будет начата с параметрами IBASE_WRITE | IBASE_CONCURRENCY | IBASE_WAIT. Описание констант для задания параметров транзакции можно найти по ссылке php.net/manual/ru/ibase.constants.php. Транзакцию необходимо завершать с помощью метода ibase_commit или ibase_rollback передавая в эти функции идентификатор транзакции. Если вместо этих функций использовать функции ibase_commit_ret или ibase_rollback_ret, то транзакция будет завершаться как COMMIT RETAIN или ROLLBACK RETAIN.

Замечание.

Умолчательные параметры транзакции подходят для большинства случаев. Дело в том что соединение с базой данных, как и все связанные с ним ресурсы существуют максимум до конца работы PHP скрипта. Даже если вы используете постоянные соединения, то все связанные ресурсы будут освобождены после вызова функции ibase_close. Несмотря на сказанное, настоятельно рекомендую завершать все выделенные ресурсы явно, вызывая соответствующие ibase_ функции.

Пользоваться функциями ibase_commit_ret и ibase_rollback_ret настоятельно не рекомендую, так как это не имеет смысла. COMMIT RETAIN и ROLLBACK RETAIN были введены для того, чтобы в настольных приложениях сохранять открытыми курсоры при завершении транзакции.

Внимание!

ibase функции не бросают исключение в случае возникновения ошибки. Часть функций возвращают false, если произошла ошибка. Обращаю ваше внимание, что результат сравнивать с false необходимо строгим оператором сравнения ===. Потенциально ошибка может возникнуть поле вызова любой ibase функции. Текст ошибки можно узнать с помощью функции ibase_errmsg. Код ошибки можно получить с помощью функции ibase_errcode.

Расширение Firebird/Interbase позволяет взаимодействовать с сервером Firebird не только посредством SQL запросов, но и используя Service API (см. функции ibase_service_attach, ibase_service_detach, ibase_server_info, ibase_maintain_db, ibase_db_info, ibase_backup, ibase_restore). Эти функции позволяют получить информацию о сервере Firebird, сделать резервное копирование, восстановление или получить статистику. Эта функциональность требуется в основном для администрирования БД, поэтому мы не будем рассматривать её подробно.

Расширение Firebird/Interbase так же поддерживает работу с событиями Firebird (см. функции ibase_set_event_handler, ibase_free_event_handler, ibase_wait_event).

Обзор расширения PDO (драйвер Firebird)

Расширение PDO предоставляет обобщённый интерфейс для доступа к различным типам БД. Каждый драйвер базы данных, в котором реализован этот интерфейс, может представить специфичный для базы данных функционал в виде стандартных функций расширения.

PDO и все основные драйверы внедрены в PHP как загружаемые модули. Чтобы их использовать, требуется их просто включить, отредактировав файл php.ini следующим образом:

Замечание

Этот шаг необязателен для версий PHP 5.3 и выше, так как для работы PDO больше не требуются DLL.

Далее нужно выбрать DLL конкретных баз данных и либо загружать их во время выполнения функцией dl(), либо включить их в php.ini после php_pdo.dll. Например:

Эти DLL должны лежать в директории extension_dir. Драйвер pdo_firebird требует, чтобы у вас была установлена клиентская библиотека fbclient.dll/gds32.dll (для UNIX подобных систем fbclient.so) соответствующей разрядности.

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

PDO использует объектно-ориентированный подход к написанию программ. Какой именно драйвер будет использоваться в PDO, зависит от строки подключения, называемой так же DSN (Data Source Name). DSN состоит из префикса, который и определяет тип базы данных, и набора параметров в виде = , разделённых точкой с запятой «;». Допустимый набор параметров зависит от типа базы данных. Для работы с Firebird строка подключения должна начинаться с префикса firebird: и иметь вид, описанный в документации в разделе PDO_FIREBIRD DSN.

Соединения устанавливаются автоматически при создании объекта PDO от его базового класса. Конструктор класса принимает аргументы для задания источника данных (DSN), а также необязательные имя пользователя и пароль (если есть). Четвёртым аргументом можно передать массив специфичных для драйвера настроек подключения в формате ключ=>значение.

Установив свойство \PDO::ATTR_ERRMODE в значение \PDO::ERRMODE_EXCEPTION, мы установили режим, при котором любая ошибка, в том числе и ошибка при подключении к БД, будет возбуждать исключение \PDOException. Работать в таком режиме гораздо удобнее, чем проверять наличие ошибки после каждого вызова ibase_ функций.

Для того чтобы PDO использовал постоянные соединения необходимо в конструктор PDO в массиве свойств передать PDO::ATTR_PERSISTENT => true.

Метод query выполняет SQL запрос и возвращает результирующий набор в виде объекта \PDOStatement. В этот метод помимо SQL запросы вы можете передать способ возвращения значений при фетче. Это может быть столбец, экземпляр заданного класса, объект. Различные способы вызова вы можете посмотреть по ссылке http://php.net/manual/ru/pdo.query.php.

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

Если в запросе используются параметры, то необходимо пользоваться подготовленными запросами. В этом случае вместо метода query необходимо вызвать метод prepare. Этот метод возвращает объект класса \PDOStatement, который инкапсулирует в себе методы для работы с подготовленными запросами и их результатами. Для выполнения запроса необходимо вызвать метод execute, который может принимать в качестве аргумента массив с именованными или неименованными параметрами. Результат выполнения селективного запроса можно получить с помощью методов fetch, fetchAll, fetchColumn, fetchObject. Методы fetch и fetchAll могут возвращать результаты в различном виде: ассоциативный массив, объект или экземпляр определённого класса. Последнее довольно часто используется в MVC паттерне при работе с моделями.

Пример использования именованных параметров.

Замечание

Для поддержки именованных параметров PDO производит предобработку запроса и заменяет параметры вида :paramname на «?», сохраняя при этом массив соответствия между именем параметра и номерами его позиций в запросе. По этой причине оператор EXECUTE BLOCK не будет работать, если внутри него используются переменные маркированные двоеточием. На данный момент нет никакой возможности заставить работать PDO с оператором EXECUTE BLOCK иначе, например, задать альтернативный префикс параметров, как это сделано в некоторых компонентах доступа.

Передать параметры в запрос можно и другим способом, используя так называемое связывание. Метод bindValue привязывает значение к именованному или неименованному параметру. Метод bindParam привязывает переменную к именованному или неименованному параметру. Последний метод особенно полезен для хранимых процедур, которые возвращают значение через OUT или IN OUT параметр (в Firebird механизм возврата значений из хранимых процедур другой).

Внимание

Нумерация неименованных параметров в методах bindParam и bindValue начинается с 1.

По умолчанию PDO автоматически подтверждает транзакцию после выполнения каждого SQL запроса, если вам необходимо явное управление транзакциями, то необходимо стартовать транзакцию с помощью метода \PDO::beginTransaction. По умолчанию транзакция стартует с параметрами CONCURRENCY | WAIT | READ_WRITE. Завершить транзакцию можно методом \PDO::commit или \PDO::rollback.

К сожалению метод beginTransaction не предоставляет возможности изменить параметры транзакции, однако вы можете сделать хитрый трюк, задав параметры транзакции оператором SET TRANSACTION.

Ниже представлена сводная таблица возможностей различных драйверов для работы с Firebird.

Возможность Расширение Firebird/Interbase PDO
Парадигма программирования Функциональная Объектно-ориентированная
Поддерживаемые БД Firebird, Interbase, Yaffil и другие клоны Interbase. Любая БД, для которой существует PDO драйвер, в том числе Firebird.
Работа с параметрами запросов Только неименованные параметры, работать не очень удобно, поскольку используется функция с переменным числом аргументов. Есть возможность работать как с именованными, так и неименованными параметрами. Работать очень удобно, однако некоторые возможности Firebird (оператор EXECUTE BLOCK) не работают.
Обработка ошибок Проверка результата функций ibase_errmsg, ibase_errcode. Ошибка может произойти после вызова любой ibase функции при этом исключение не будет возбуждено. Есть возможность установить режим, при котором любая ошибка приведёт к возбуждению исключения.
Управление транзакциями Даёт возможность задать параметры транзакции. Не даёт возможность задать параметры транзакции. Есть обходной путь через выполнение оператора SET TRANSACTION.
Специфичные возможности Interbase/Firebird Есть возможность работать с расширениями Service API (backup, restore, получение статистики и т.д.), а также с событиями базы данных. Не позволяет использовать специфичные возможности, с которыми невозможно работать, используя SQL.

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

Выбор фреймворка для построения WEB приложения

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

Итак, мы решили использовать паттерн MVC. Однако написание приложение с использованием этого паттерна не такая простая задача как кажется, особенно если мы не пользуемся сторонними библиотеками. Если всё писать самому, то необходимо решить множество задач: автозагрузка файлов .php, включающих определение классов, маршрутизация и др. Для решения этих задач было создано большое количество фреймворков, например Yii, Laravel, Symphony, Kohana и многие другие. Лично мне нравится Laravel, поэтому далее я буду описывать создание приложения с использованием этого фреймворка.

Установка Laravel и создание проекта

Прежде чем устанавливать Laravel вам необходимо убедится, что ваше системное окружение соответствует требованиям.

  • PHP >= 5.5.9
  • PDO расширение для PHP (для версии 5.1+)
  • MCrypt расширение для PHP (для версии 5.0)
  • OpenSSL (расширение для PHP)
  • Mbstring (расширение для PHP)
  • Tokenizer (расширение для PHP)

Laravel использует Composer для управления зависимостями. Поэтому сначала установите Composer, а затем Laravel.

Самый простой способ установить composer под windows – это скачать и запустить инсталлятор Composer-Setup.exe. Инсталлятор установит Composer и настроит PATH, так что вы можете вызвать Composer из любой директории в командной строке.

Если необходимо установить Composer вручную, то необходимо запустить

Этот скрипт осуществляет следующие действия:

  • Скачивает инсталлятор в текущую директорию
  • Проверяет инсталлятор с помощью SHA-384
  • Запускает скрипт инсталляции
  • Удаляет скрипт инсталляции

После запуска этого скрипта у вас появится файл composer.phar (phar – это архив) — по сути это PHP скрипт, который может принимать несколько команд (install, update, . ) и умеет скачивать и распаковывать библиотеки. Если вы работаете под windows, то вы можете облегчить себе задачу, создав файл composer.bat и поместив его в PATH. Для этого необходимо выполнить команду
echo @php «%

Подробнее об установке composer смотри здесь.

Теперь устанавливаем сам Laravel:

Если установка прошла успешно, то приступаем к созданию каркаса проекта.

Ждём завершения, после чего у нас будет создан каркас проекта. Описание структуры каталогов можно найти в документации по Laravel. Нас будут интересовать следующие каталоги:

  • app – основной каталог нашего приложения. В корне каталога будут размещены модели. В подкаталоге Http находится все, что касается работы с браузером. В подкаталоге Http/Controllers – наши контроллеры.
  • config – каталог файлов конфигурации. Подробней о конфигурировании будет написано ниже.
  • public – корневой каталог web приложения (DocumentRoot). Содержит статические файлы — css, js, изображения и т.п.
  • resources — здесь находятся шаблоны (Views), файлы локализации и, если таковые имеются, рабочие файлы LESS, SASS и js-приложения на фреймворках типа ReactJS, AngularJS или Ember, которые потом собираются внешним инструментом в папку public.

В корне папки нашего приложения есть файл composer.json, который описывает, какие пакеты, потребуются нашему приложению помимо тех, что уже есть в Laravel. Нам потребуется два таких пакета: «zofe/rapyd-laravel» — для быстрого построения интерфейса с сетками (grids) и диалогами редактирования, и «sim1984/laravel-firebird» — расширение для работы с СУБД Firebird. Пакет «sim1984/laravel-firebird» является форком пакета «jacquestvanzuydam/laravel-firebird» поэтому его установка несколько отличается (описание отличий пакета от оригинального вы можете найти в статье «Пакет для работы с СУБД Firebird в Laravel»). Не забудьте установить параметр minimum-stability равный dev, так как пакет не является стабильным, а так же добавить ссылки на репозиторий.

В секции require добавьте требуемые пакеты следующим образом:

Теперь можно запустить обновление пакетов командой (запускать надо в корне веб приложения)

После выполнения этой команды новые пакеты будут установлены в ваше приложение. Теперь можно приступить к настройке. Для начала выполним команду

которая создаст дополнительные файлы конфигурации для пакета zofe/rapyd.

В файле config/app.php добавим два новых провайдера. Для этого добавим две новых записи в ключ providers

Теперь перейдём к файлу config/databases.conf, который содержит настройки подключения к базе данных. Добавим в ключ connections следующие строки

Поскольку мы будем использовать наше подключение в качестве подключения по умолчанию, установим следующее

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

В файле конфигурации config/rapid.php изменим отображение дат так, чтобы они были в формате принятом в России:

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

Создание моделей

Фреймворк Laravel поддерживает ORM Eloquent. ORM Eloquent — красивая и простая реализация паттерна ActiveRecord для работы с базой данных. Каждая таблица имеет соответствующий класс-модель, который используется для работы с этой таблицей. Модели позволяют читать данные из таблиц и записывать данные в таблицу.

Создадим модель заказчиков, для упрощения этого процесса в Laravel есть artisan команда.

Этой командой мы создаём шаблон модели. Теперь изменим нашу модель так, чтобы она выглядела следующим образом:

Обратите внимание, мы используем модифицированную модель Firebird\Eloquent\Model из пакета sim1984/laravel-firebird в качестве базовой. Она позволяет воспользоваться последовательностью, указанной в свойстве $sequence, для генерирования значения идентификатора первичного ключа.

По аналогии создадим модель товаров – Product.

Теперь создадим модель для шапки счёт-фактуры.

В этой модели можно заметить несколько дополнительных функций. Функция customer возвращает заказчика связанного со счёт фактурой через поле CUSTOMER_ID. Для осуществления такой связи используется метод belongsTo, в который передаются имя класса модели и имя поле связи. Функция lines возвращают позиции счёт-фактуры, которые представлены коллекцией моделей InvoiceLine (будет описана далее). Для осуществления связи один ко многим в функции lines используется метод hasMany, в который передаётся имя класса модели и поле связи. Подробнее о задании отношений между сущностями вы можете почитать в разделе Отношения документации Laravel.

Функция pay осуществляет оплату счёт фактуры. Для этого вызывается хранимая процедура SP_PAY_FOR_INVOICE. В неё передаётся идентификатор счёт фактуры. Значение любого поля (атрибута модели) можно получить из свойства attributes. Вызов хранимой процедуры осуществляется с помощью метода executeProcedure. Этот метод доступен только при использовании расширения sim1984/laravel-firebird.

Теперь создадим модель для позиций счёт фактуры.

В этой модели есть функция product, которая возвращает продукт (модель App/Product), указанный в позиции счёт фактуры. Связь осуществляется по полю PRODUCT_ID с помощью метода belongsTo.

Вычисляемое поле SumPrice вычисляется с помощью функции getSumPriceAttribute. Для того чтобы это вычисляемое поле было доступно в модели, его имя должно быть указано в массиве имён вычисляемых полей $appends.

В этой модели мы переопределили операции insert, update и delete так, чтобы они выполнялись, используя хранимые процедуры. Эти хранимые процедуры помимо собственно операций вставки, редактирования и удаления пересчитывают сумму в шапке накладной. Этого можно было бы и не делать, но тогда пришлось бы выполнять в одной транзакции модификацию нескольких моделей. Как это сделать будет показано далее.

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

Этот конструктор запросов является довольно мощным средством для построения и выполнения SQL запросов. Вы можете выполнять также фильтрация, сортировку и соединения таблиц, например

Однако гораздо удобнее работать с использованием моделей. Описание моделей Eloquent ORM и синтаксиса запроса к ним можно найти по ссылке laravel.ru/docs/v5/eloquent. Так для получения всех элементов коллекции поставщиков необходимо выполнить следующий запрос

Следующий запрос вернёт первые 20 поставщиков отсортированных по алфавиту.

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

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

Для изменения запись её необходимо найти, изменить необходимые атрибуты и сохранить методом save.

Для удаления записи её необходимо найти и вызвать метод delete.

Удалить запись по ключу можно и гораздо быстрее с помощью метода destroy. В этом случае можно удалить модель не получая её экземпляр.

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

Теперь поговорим немного о транзакциях. Что это такое я рассказывать не буду, а лишь покажу, как их можно использовать совместно с Eloquent ORM.

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

Создание контроллеров и настройка маршрутизации

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

В первом случае мы регистрируем обработчик GET запроса для корня сайта, во втором – для POST запроса с маршрутом /foo/bar.

Вы можете зарегистрировать маршрут сразу на несколько типов HTTP запросов, например

Из маршрута можно извлекать часть адреса и использовать его в качестве параметров функции-обработчика

Параметры маршрута всегда заключаются в фигурные скобки. Подробнее о возможности настройки маршрутизации вы можете посмотреть в документации глава «Маршрутизация». Маршруты настраиваются в файле app/Http/routes.php в Laravel 5.2 и routes/wep.php в Laravel 5.3.

Вместо того чтобы описывать обработку всех запросов в едином файле маршрутизации, мы можем организовать её использую классы Controller, которые позволяют группировать связанные обработчики запросов в отдельные классы. Контроллеры хранятся в папке app/Http/Controllers.

Все Laravel контроллеры должны расширять базовый класс контроллера App\Http\Controllers\Controller, присутствующий в Laravel по умолчанию. Подробнее о написании контроллеров вы можете почитать в документации в главе HTTP-Контроллеры.

Напишем наш первый контроллер.

Теперь необходимо связать методы контроллера с маршрутом. Для этого в routes.php (web.php) необходимо внести строку

Здесь имя контроллера отделено от имени метода символом @.

Для быстрого построения интерфейса с сетками и диалогами редактирования будем использовать пакет «zofe/rapyd». Мы его уже подключили ранее. Классы пакета zofe/rapyd берут на себя построение типичных запросов к моделям Eloquent ORM. Изменим контроллер заказчиков так, чтобы он выводил данные в сетку (grid), позволял производить их фильтрацию, а также добавлять, редактировать и удалять записи через диалоги редактирования.

Laravel по умолчанию использует шаблонизатор blade. Функция view находит необходимый шаблон в директории resources/views, делает необходимые замены в нём и возвращает текст HTML страницы. Кроме того, она передаёт в него переменные, которые становятся доступными в шаблоне. Описание синтаксиса шаблонов blade вы можете найти в документации в разделе Шаблонизатор Blade.

Шаблон для отображения заказчиков выглядит следующим образом:

Данный шаблон унаследован от шаблона example и переопределяет его секцию body. Переменные $filter и $grid содержат HTML код для осуществления фильтрации и отображения данных в сетке. Шаблон example является общим для всех страниц.

Этот шаблон сам унаследован от шаблона master, кроме того он подключает шаблон menu. Меню довольно простое, состоит из трёх пунктов Заказчики, Продукты и Счёт фактуры.

В шаблоне master подключаются css стили и JavaScript файлы с библиотеками.

Шаблон редактора заказчика customer_edit выглядит следующим образом

Контроллер товаров сделан аналогично контроллеру поставщиков.

Контроллер счёт фактур является более сложным. В него добавлена дополнительная функция оплаты счёта. Оплаченные счёт фактуры подсвечиваются другим цветом. При просмотре счёт фактуры отображаются так же её позиции. Во время редактирования счёт фактуры есть возможность редактировать и её позиции. Далее я приведу текст контроллера с подробными комментариями.

Редактор счёт фактур имеет не стандартный для zofe/rapyd вид, поскольку нам необходимо выводить сетку с позициями счёт фактур. Для этого мы изменили шаблон invoice_edit следующим образом.

Теперь, когда все контроллеры написаны, изменим маршруты так, чтобы наш сайт на стартовой странице открывал список счёт фактур. Напоминаю, что маршруты настраиваются в файле app/Http/routes.php в Laravel 5.2 и routes/wep.php в Laravel 5.3.

Здесь маршрут /invoice/pay/ выделяет идентификатор счёт фактуры из адреса и передаёт его в метод payInvoice. Остальные маршруты не требуют отдельного пояснения.

Напоследок приведу несколько скриншотов получившегося веб приложения.

Добавить комментарий