Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Здравствуйте.
Я использую полиморфические связи для хранения изображений, и что бы в каждой модели не писать связь, я вынес эту связь в трейт.
Есть метод getImages($type) {} в методе идет запроос на получение всех изображений по типу.
Проблема в том, что я использую этот метод в шаблоне 2 раза, и запросы дублируются.
Вопрос в том, как можно заранее поставить where в эту связь, что бы каждый раз не писать %%$this->with([’images ⇒ function($q){
$q-where(’type’, $type)}]);%%
Добрый вечер.
При проектировании БД, у меня возник вопрос. Вот у меня есть обьекты, к примеру Рестораны, Достопремечательности, и отели. У них у всех одинаковые свойства (имя, описание, местоположение…). Как будит лучше разделить эти обьекты, создав одну таблицу, и добавить поле type типа enum. Или для каждого обьекта создать свою таблицу? В дальнейшем типы обьектов могут добавляться.
Спасибо
Добрый вечер.
Если я закешировал конфиг, и например делаю что то вроде config(['app.timezone' => $timezone]) то как ларавел на это реагирует? Он удаляет кеш конфигов?
И где лучше всего ставить это значение? В сервис провайдере? А если я ставлю не только таймзон, а еще и дебаг, урл и тд, то сильно ли это нагружает систему?
Здравствуйте.
У меня есть класс в котором метод принимает callable.
Вот пример.
class Button
{
protected $data = [];
public function build($method)
{
if(is_callable($method)) {
$method();
}
if(is_array($method)) {
$this->data['buttons'] = $method;
}
}
public function addButton(array $button = [])
{
$this->data['buttons'] = $button;
return $this;
}
}
Я хочу сделать возможность добавлять кнопку массивом, или использовать колбек. Примерно так:
// при помощи колбека
public function index()
{
$this->button->build(function ($button) {// Как сделать что бы параметр $button былл экземпляром класса Button?
$button->addButton(['a' => 'b']);
});
}
// массивом
public function index()
{
$this->button->build(['a' => 'b']);
}
Сам вопрос, как сделать что бы параметер в колбеке был экземпляром класса Button?
- Спасибо. Мне кажется, что для такого функционала это количество запросов вполне нормальное. Медленно работает?
Сейчас нормально работает, но боюсь что при нормальным кол-стве визиторов, все сломается к чертям…
А можешь сказать сколько метров оперативы использует ларавел в каком нибудь из твоих проектов, схожим по функционаллу с моим?
- Который генерирует 30 запросов.
// Controller
/**
* Show product page
*
* @param string $slug
* @return \Illuminate\Contracts\View\Factory
*/
public function showProduct($slug)
{
$product = $this->product->show($slug);
return view('frontend.pages.product.product', [
'product' => $product,
'attributes' => $this->attribute->getCombinations($product->variation_ids),
'features' => $this->feature->getProductFeatures($product->feature_ids),
]);
}
// Model Product
/**
* Show product
*
* @param string $slug
* @return mixed
*/
public function show($slug)
{
return $this->with(
'images',
'carriers',
'variations.combinations.attribute',
'features',
'reviews',
'reviews.images',
'video',
'categories'
)->actual()->findBySlug($slug);
}
// Model Attribute
/**
* Get product combinations
* Size - S, Color - Black
* Size - M, Color - Black
* Etc..
*
* @param array $variationIds
* @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|static[]
*/
public function getCombinations(array $variationIds = [])
{
return $this->whereHas('values', function($q) use($variationIds){
$q->whereHas('combinations', function($q) use($variationIds) {
$q->whereIn('product_variation_id', $variationIds);
});
})->with([
'values' => function($q) use($variationIds) {
$q->whereHas('combinations', function($q) use($variationIds) {
$q->whereIn('product_variation_id', $variationIds);
});
},
])->get();
}
// Model Features
/**
* Get product features
*
* @param array $featureIds
* @return \Illuminate\Database\Eloquent\Collection
*/
public function getProductFeatures(array $featureIds)
{
return $this->whereHas('values', function($q) use($featureIds){
$q->whereIn('id', $featureIds);
})->with(['values' => function($q) use($featureIds){
$q->whereIn('id', $featureIds);
}])->get();
}
Этов се сейчас создает 13 — 15 запросов. Но если использовать структуру для n-ного кол-ства языков как я писал выше вида
products -> product_langs categories -> cateory_langs attributes -> attribute_langs attribute_values -> attribute_value_langs features -> feature_langs feature_values -> feature_values_lang ....
То запросы в 2 раза вырастут везде. Вот и хочу узнать, как максимально можно оптимизировать нагрузку.
И опять я вернулся к этому вопросу. Использование в каждой записи поле land_id оказалось неудобным, потому что при сохранении нового ресурса, создаются ресурсы с разными идентификаторами. К примеру создаем категории:
- id - name - lang_id ----------- id: 14 name: Новая категория lang_id: 1 id: 15 name: New category lang_id: 2
По этому решил сменить структуру бд на такую
// categories (hasMany CategoryLang) - id - created_at ... // category_lang - id - category_id - lang_id - name
При такой структуре будит по 2 запроса уже, а не один. По этому хотелось бы максимально это все оптимизировать (составные индексы, что то еще). Особеннл на странице товара, где идет 15 переводимых ресурсов. Получается 30 запросов к бд.
Посоветуйте пожалуйста как максимально оптимизировать запросы? Спасибо!
Здравствуйте.
Такой вопрос: покупатель добавил товары в корзину, прошел этапы оформления заказа, и подошел к этапу оплаты. Тут у меня возник вопрос, а когда создавать ордер? До оплаты, или после оплаты?
Если до оплаты, то ставить статус 'не оплачен', после оплаты обновлять статус и ставить 'оплачен'?
Кто как делает, поделитесь пожалуйста опытом.
Спасибо!
- Например, можно проиндексировать товар, вне зависимости от типа price:
Спасибо. Сразу не подумал об этом решении.
- В price хранишь цену как integer. Например, 20 долларов хранишь как 20000, перед сохранением или после извлечения данных из таблицы конвертируешь как нужно с помощью читателей и преобразователей (accessors & mutators или setters & getters).
Я так и сделал. но сейчас выяснилось что, когда я заношу в базу к примеру 3.99, бд сама его к 4 приводит. Но я не добавляю 3 нолика. Вообще запутался. Можно примеры как заносить такую цену, и получать (преобразовывать) в мутаторе если не трудно.
- Как бы я делал (и делал big_smile ) ресурсы на разных языках. Во первых, даже если одна статья это дословный перевод другой, это всё равно разные ресурсы, у них должен быть разный URL. Хотя вероятно у них будут перекрёстные ссылки. Отсюда естественным образом вытекает то, что достаточно одной таблицы articles. А атрибут язык это одно из полей таблицы. Для перекрёстных ссылок типа «варианты статьи на других языках» можно завести таблицу связку, чтобы организовать отношение many-to-many.
- Нужно не мутатор использовать, а написать функцию в модели, типо…
Спасибо! для меня с мутатором как то по удобнее было. В шаблоне {{ $model->image }} и все.
- В зависимости от того, насколько сильно требуется чистый код.
- Я обычно это делают где-то в сервисном слое, либо в ресурсах, метод toArray (https://laravel.com/docs/5.5/eloquent-resources), либо в слое файлового апи (если он имеется и/или необходим).
- Но и простого метода в модельке для простых случаев будет достаточно.
Спасибо за ответ!
Я не могу никак перейти на 5.5, по этому ресурсы не доступны.
- P.S. правда я использую фрактал http://fractal.thephpleague.com/) вместо ресурсов ларавела.
Добрый день. тут недавно в какой то теме было обсуждение насчет того что сервер должен отдавать картинки.
Так вот, я отдаю не сами картинки, а ссылки на них так:
// Model
public function getImageAttribute()
{
return asset(self::IMAGE_PATH . $this->id . '.jpg')
}
Вопрос в том, таким образом я отдаю только ссылку на картинку, или php читает эту картинку, а потом отдает ее?
Каким образом вы отдаете картинки?
Спасибо!
Здравствуйте.
Этот вопрос уже здесь поднимался, но та структура которая предложена там, меня не устраивает.
Во многих CMS с идет мультиязычность используя несколько таблиц, к примеру: articles и articles_lang. Но я не хочу использовать такую структуру, что бы не было по два запроса на один ресурс. Может как то по другому можно?
В голову пришло только вот это.
Создаем таблицу языков. Когда посетитель заходит на сайт, то определяем его язык браузера, делаем запрос в базу с языками, и выбираем язык по коду. Если такого языка в базе нет, выбираем дефолтный язык. Затем ставим ид этого языка в сессию, а потом глобальным скоупом, выбираем записи where('lang_id', $lang->id)
Нормально ли так делать? И есть ли еще какие то варианты. Спасибо.
Здравствуйете.
Есть 3 таблици связанные м2м
Carriers
- id
- name
...
Zones
- id
- name
...
Carrier Zone
- carrier_id
- zone_id
- price
Связи все правильно настроены, и все четко сохраняется. Проблема при обновлении.
К примеру захожу редакировать carrier #1, Надо выделить активные зоны, и цены.Вот как в шаблоне это выглядит.
@foreach($zones as $i => $zone)
<div class="form-group row">
<label class="control-label col-sm-3" for="zone-{{ $zone->id }}">
<span>{{ $zone->name }}</span>
</label>
<div class="col-sm-1">
<label>
<input type="checkbox" name="zone[{{ $i }}]" value="{{ $zone->id }}" {{ old('zone.' . $i, in_array($zone->id, $carrier->old_zones)) ? 'checked' : '' }}>
</label>
</div>
<div class="col-sm-2 p-x-0">
<div class="input-group">
<span class="input-group-addon">$</span>
<input type="number" name="price[{{ $i }}]" class="form-control form-control-custom" value="{{ old('price.' . $i) }}" id="zone-{{ $zone->id }}" />
</div>
</div>
</div>
@endforeach
// Model Carrier
/**
* Get old carrier zones
*
* @return mixed
*/
public function getOldZonesAttribute()
{
return $this->zones->pluck('id')->all();
}
/**
* Gel old carrier zone prices
*
* @return mixed
*/
public function getOldPricesAttribute()
{
return $this->zones->pluck('pivot.price')->all();
}
Вот как поставить старую цену? С активной зоной нет проблем, а вот с ценой. Помогите пожалуйста
Добрый день.
Есть главный контроллер
/**
* @var Page
*/
protected $page;
/**
* BackendBaseController constructor
* @param Page $page
*/
public function __construct(Page $page)
{
$this->page = $page;
}
В нем внедряю сервис Page
Другие контроллеры наследуют главный контроллер. И когда перегружаю конструктор, приходится все время этот сервис передовать в конструктор.
/**
* BackendShopController constructor
*
* @@param Page $page
* @param Shop $shop
*/
public function __construct(Shop $shop, Page $page)
{
parent::__construct($page);
$this->shop = $shop;
}
Как избавиться от инъекции этого сервиса в чаилд контроллерах? Пытался в сервис провайдере добавить
$this->app->bind('App\Services\Page');
Но он жалуется на то что я его не передал в чаилд контроллере.