Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
inner join `ART_LOOKUP` as `ART_LOOKUP2 FORCE KEY (PRIMARY)` on `ART_LOOKUP2`.`ARL_ART_ID` = `ART_LOOK.`ARL_ART_ID`
думаю причина в этом
SmsUpdaterController же должен являться некой общей точкой с логикой именно для загрузки новых смс.
Тогда имеет смысл перенести его в Console\Command и вызывать из командной строки ./artisan sms:import
Идея в том, чтобы разделить цикл от получения смс до ее обработки на несколько этапов, где будут отрабатывать свои контроллеры.
Для этого придуманы события (Event). Пример вызова из контроллера(или репа):
Event::fire(new SMS($dbSms));
Потребуется описать слушателей (Listeners) события SMS в EventServiceProvider:
SMS::class => [
listen1::class,
listen2::class,
listen3::class,
...
],
подробно про события тут
Но возможно я неправильно понял задачу и здесь более подойдут очереди.
Дело в том, что события передают всем слушателям один и тот же объект dbSms, а в очередях можно создавать задачи разным очередям и модифицировать информацию из одной задачи в другую.
Видимо, я не до конца понимаю смысл контроллеров и моделей. Поэтому вынес логику в отдельные контроллеры.
попробую на трех пальцах...
Запрос(Request) - специальный класс, в котором прописывается валидация входных данных
Контроллер - принимает подготовленный запрос и передает его в реп. Контроллер определяет какие именно методы HTTP доступны этому конкретному ресурсу (GET, POST, DELETE..)
Репозитарий - промежуточная модель, консолидирующая модели к БД, логику, какие то вызовы внешнего апи, все что угодно в общем. Данные из репа возвращаются в контроллер
Вьюха(view) - ответ системы. Может быть бинарной, текстовой(html, json, cvs..). Для преобразования данных в json хорошо подходят Resources
Как правильно к ней подключаться пока не знаю,
изи.. как обычно
config/database.php:
//основная
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'homestead'),
'username' => env('DB_USERNAME', 'homestead'),
'password' => env('DB_PASSWORD', 'homestead'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
],
//"внешняя"
'mysql2' => [
'driver' => 'mysql',
'host' => env('DB_HOST_EXT', '127.0.0.1'),
'port' => env('DB_PORT_EXT', '3306'),
'database' => env('DB_DATABASE_EXT', 'homestead'),
'username' => env('DB_USERNAME_EXT', 'homestead'),
'password' => env('DB_PASSWORD_EXT', 'homestead'),
'unix_socket' => env('DB_SOCKET_EXT', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
],
.env
DB_HOST_EXT=127.0.0.1
DB_DATABASE_EXT=mysqlbase
DB_USERNAME_EXT=login
DB_PASSWORD_EXT=pass
ну и в модели
class SomeModel extends Eloquent {
protected $connection = 'mysql2';
}
Приветствую.
Модель нужна для взаимодейстия таблицей, как с объектом, а контроллер для взаимодействия с таблицей уже через модель. Вроде верно. Поправьте если не так.
Лучше сделать немного не так.
Контроллер сделать тонким, а всю логику переложить в реп, который уже будет вызвать нужные ему модели бд. Т.е. примерно так:
/App/Http/Controllers/Frontend/SmsController.php:
<?php
namespace App\Http\Controllers\Frontend;
use App\Repositories\Frontend\SmsRepository;
class SmsController extends WebController
{
/**
* Конструктор
*
* @param SmsRepository $model
*/
public function __construct(SmsRepository $model)
{
$this->model = $model;
parent::__construct();
}
}
/App/Repositories/Frontend/SmsRepository.php:
namespace App\Repositories\Frontend;
use App\Models\db\dbSms;
class SmsRepository extends OptionsRepositary
{
//основная логика работы приложения
}
Более подробно о таком подходе см тут же на сайте, в разделе "Хорошие практики Laravel"
Так как смс приходят много, то они требуют постоянной подгрузки. Посему был создан еще один контроллер с названием "SmsUpdateController"
Вот тут ниче не понял. Зачем был создан еще один контроллер? Чем один не подошел? Что значит "много"?
Тут нужно сделать отступление и указать на не вполне очевидную, но задокументированную вещь: в Laravel искаропки есть ресурс-контроллеры, которые можно использовать в роутах напрямую, вот так:
Route::resources([
'sms' => 'SmsController',
]);
При этом в самом SmsController могут быть(а могут и нет) реализованы следующие методы: ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy']
Это значит, что к одному и тому же контроллеру при разных способах обращения (GET, POST, DELETE..) будут вызываться разные методы. Поэтому совсем необязательно(а я считаю, что и вредно) создавать колхоз со всякими там public function setValueOnUpdate с последующим прописанием этого пути в роутер. Вышеуказанных методов более чем достаточно, если нет, то Вы делаете что то не торт.
В нем мною определен основной метод main()
ну вот как раз, то, что я писал выше...
предланает использовать ассоциативный массив и передввать его на всех циклах отработки загрузочного модуля
Из описания ничего не понятно, что за массив, что за циклы отработки, что за загрузка...
У ларавель есть несколько способов работы с долгими задачами - например очереди, но если у Вас некий центр обработки, в котором пришедшая смс должна пройти по разным стадиям в разных обработчиках, то более разумно использовать Enent:
$sms = new dbSms;
$sms->fill($data);
$sms->save();
Event::fire(new SMSEvent($sms));
при этом все слушатели события SMSEvent получат экземпляр dbSms в качестве сообщения.
Куда его прописывать? Создать папку Library в App?
Модели бд обычно прописываются в App/Models/db например... Library - это другое, тут обычно находятся общие библиотеки, ну например какие то парсеры, методы вычисления углов по пятнам на Солнце итп.
А как правильно подключить класс?
В наш то просвещенный век уже есть PSR-2, который описывает как именно именовать классы через наймспейсы.
<?php
namespace App\Models\db;
use Illuminate\Database\Eloquent\Model
class dbSms extends Model
{
//необязательно, имя таблицы подставится из имени класса
protected $table = 'sms';
}
Затем, там где надо используешь
use App\Models\db\dbSms;
Вообще и далее по ходу разработки понпдобятся собственные классы. Например, класс с регулярками для разбора смс
вот ему самое место в Library
стоит ли хранить системную информацию об объекте смс в отдельной таблице sms_meta? Или же пару лишних полей не испортят таблицу sms?
В mySql есть замечательное поле типа Json. Нет никакой необходимости создавать еще одну таблицу(это вообще то лишняя нагрузка на бд), можно просто создать поле.
th1scold, мы долго в угадайку играть будем?
Конфиг queue.php покажите
Как человек, измученный нарзаном, у меня возникают квантовые запутанности и мне не понятно, в чем сложности..
1. Как запустить Elasticsearch локально?
Зависит от того, где он установлен, для локалхоста обычно это сервис. В debian-like OS будет
service elasticsearch start
2. Виртуальный _хостинг_ это когда у тебя могучая кучка возможностей, но все они прописаны хостером? Тогда увы, установить что либо, не согласованное с хостером будет невозможно. Переходите хотя бы на VPS
Для локальной разработки я использую windows и laragon - php 7.3.3 apache 2.4.35
Соболезную.
И вот, я устанавливаю Scout, Elasticsearch и Scout Elasticsearch Driver.
И вот тут у меня возникает резонный вопрос...
Предполагаю, что нужно добавить запись в `\sites-enabled\aspro.loc.conf`
Вопрос остается прежним...
Как быть? Что я настроил не так?
Для работы с эластиком я использую Elasticquent
Но даже он не поддерживает искаропки elasticsearch 7+ и приходится немного докостыливать. Подключение в моделях у меня происходит следующим образом
use Illuminate\Database\Eloquent\Model
class esSearch extends Model
{
use ElasticSearchTrait;
/**
* Обновляет поисковый индекс.
* Если потребуется в mongo - перенести код в Trait
* @param array $options
*/
public function finishSave(array $options)
{
parent::finishSave($options);
$this->addToIndex();
}
/**
* Удаляет модель из индекса
* @return bool|null
*/
public function delete()
{
$res = parent::delete();
if ($res) {
$this->removeFromIndex();
}
return $res;
}
}
и затем в самой модели
class mysqlModel extends esSearch
{
}
Такой подход делает работу с моделью совершенно прозрачной, достаточно любую модель базыданных(любой опять же, хоть монго, хоть мускл, хоть редис) отнаследовать от esSearch и далее можно применять запросы к эластику
esSearch::searchByQuery($options);
возможно просто опечатка, но почему @removeUserFromGroup, а в контроллере removeUser?
Ну а по вопросу, попробуй добавить
public function removeUser(UserRequest $request, int $user_id): SuccessResponse
вероятно(вангую), шта .env QUEUE_CONNECTION=sync, а не датабейз
Лучшим вариантом(и более универсальным) будет закинуть их в ВТ и сделать джоин.
Но.. если номеров не сильно много, можно просто
->whereIn('number', ['8800-',...])
$request->file()
не?
Да, правильно.
Отличается тем, что
1. Передача логин-пароля труЪ джыдаи делают через https и обязательно POST
2. При утечке налево логин-пароля учетка блочится(и вообще пароли полезно менять раз в 2 месяца или чаще) а при токене под удар подпадают все пользователи API
3. т.к. по факту токен - это один пользователь совершенно не представляется возможным разделить действие API
пользователь предполагается один
нет ничего более постоянного, чем временное. А гарантий, что такой пользователь один и останется обычно просто нет.
Для каких целей вообще токен, если можно в заголовках передавать логин пароль и проверять его?
можно и с каждым. Но больше телодвижений: создать хэш, сделать запрос к БД, сверить...
С токеном в кэшах - просто проверить есть такой ключ в кэше или нет.
Решение - хрень полная.. Первый кто получит API_KEY или подсмотрит его вирешарком сольет его всем желающим
Ко всему не отслеживается кто из пользователей создает запрос, а значит нет разделения на полномочия пользователей.
1. Для API лучше задать свой собственный роут исправив провайдер RouteServiceProvider
public function map()
{
$this->mapApiRoutes();
...
}
В mapApiRoutes отключаем ->middleware('web') которая и делает csrf, для API он не нужен
2. Создайте отдельный роут и контроллер к нему, создающий авторизацию и выдающий одноразовый ключ(ну или сессию на 20-30 минут)
3. Все последующие запросы осуществляйте с передачей этого ключа, например мы делаем через X-Session-Token: в хедере запросов, дабы отделить параметры запроса от технических коннектов к системе.
4. Для хранения временных токенов идеально подходит Cache - у него есть параметр длительности хранения.
Да прибудет с Вами святой Laravel и пророк его Eloquent
Azmandus, я может быть, чего не знаю.. но как на mysql сделать нечеткий поиск, например?
"почти мгновенно" - это вообще ниочем. Сколько в сухих цифрах?
ElasticSearch. Без вариантов)