yii2-advanced, база MariaDB. Сделал скрипт, который подтягивает данные из 3 таблиц и сопоставляет данные так:
public function matchImage()
{
$this->image = UploadedFile::getInstances($this, 'image');
if ($this->image && $this->validate()) {
$products = Products::find()->all();
foreach ($products as $product) {
$barcodes = ProductsBarcodes::find()->where(['product_id' => $product->id])->all();
foreach ($barcodes as $barcode) {
foreach ($this->image as $image) {
$origName = "$image->baseName";
$exploded = explode("_", $origName);
if (isset($exploded[1])) {
$origName = $exploded[0];
}
if ($origName == $barcode->barcode) {
static::newImages($product->id, $image);
}
}
}
}
}
}
public function newImages($productId, $image)
{
$array = Images::find()->where(['product_id' => $productId])->all();
$dir = "uploads/products";
$num = count($array);
$name = $productId . "_" . "$num.$image->extension";
$model = new Images();
$main = 0;
foreach ($array as $mainimage) {
if ($mainimage->main) {
$main = 1;
}
}
if (!$main) {
$model->main = 1;
}
$model->url = $name;
$model->product_id = $productId;
if($model->validate() && $model->save()) {
$image->saveAs("$dir/$name");
return true;
}
else {
return false;
}
}
На тестовой базе создал эти 3 таблицы, все работает нормально.
На второй тестовой базе (дамп с продакшена) в таблице products_barcodes
нет поля id
, т.к. это таблица one-to-many
.
И вот здесь выпадает ошибка :
Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes)
//мало памяти
Это из-за того, что нету id
? Можно ли как-то переписать скрипт под таблицу без id
?
P.S.
$products = Products::find()->joinWith('product_barcode')->where(['id' => 'product_barcode.product_id'])->all();
public function getProductsBarcodes()
{
return $this->hasMany(ProductsBarcodes::className(), ['product_id' => 'id']);
}
Непонятно для чего тут нужен $products = Products::find()->all();
, если у ProductsBarcodes есть поле product_id. Первый форич убираем?
Метод newImage() хорошо, но ведь он в цикле вызывается, а в нем обращение к БД. Что мешает получить сразу все Images в массив с ключами product_id одним запросом и выбрать не все поля, а только main (судя по коду)?
$this->images = Images::find()->select('main')->indexBy('product_id')->all();
Затем уже делаем форич $this->images[$productId]
или обходимся без форича, если выбрать только те записи, у которых main больше 0 (или что там должно быть). Достаточно будет проверить наличие $this->images[$productId]
и не надо будет каждый раз перебирать массив, и сам массив будет меньше.
Уверен, что это значительно снизит прожорливость.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Подскажите пожалуйста библиотеку(и) для работы с Nested Set, чтобы была возможность перемещать узлыВерсия php 5