Mahdi
Mahdi

Reputation: 115

Allowed memory error in getting data from db in laravel

I'm trying to get all posts from database and show the in a view. The posts that I want are stored in database with post_type = product.

I got this error:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 62918656 bytes)

this is my Model:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class GetPostModel extends Model
{
    /**
     * @param $filed
     * @param $value
     * @return mixed
     */
    static function get_posts_by_filed($filed, $value)
    {
        $result = DB::table('posts')->where($filed, $value);
        return $result;
    }
}

this is what I do in Controller:

public function all_products_page(Request $request)
{

    //getting the products
    $all_products = GetPostModel::get_posts_by_filed('post_type', 'product');
    echo '<pre>';
    print_r($all_products);
    echo '</pre>';
}

Upvotes: 2

Views: 1880

Answers (2)

FULL STACK DEV
FULL STACK DEV

Reputation: 15951

This is happening because u are missing get()

public function all_products_page(Request $request)
{

//getting the products
$all_products = GetPostModel::get_posts_by_filed('post_type', 'product')->get();
echo '<pre>';
print_r($all_products);
echo '</pre>';
 }

Upvotes: 2

Bogdan Cismariu
Bogdan Cismariu

Reputation: 151

It seems that you have too many entries in your database and they all get loaded into PHP memory.

The easy solution would be to increase PHP memory limit:

ini_set('memory_limit', '512M');

The correct solution would be to try to protect your memory usage and restrain from processing all the information at once. Also, keep in mind that sending too much information to the browser might also affect performance on the client side.

A possible approach would be to use pagination. Laravel already has this integrated in the query builder: https://laravel.com/docs/5.6/pagination

If passing through all the posts is absolutely necessary, you might want to chunk results as described in the Eloquent documentation: https://laravel.com/docs/5.6/eloquent#chunking-results

Also, a more Laravel like approach would look something like this:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $table = 'posts';

    /**
     * Scope a query to only include products
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeProducts($query)
    {
        return $query->where('post_type', 'product');
    }
}

And then, your Controller would look like this:

<?php

public function all_products_page(Request $request)
{

    Post::products()->chunk(100, function ($products) {
        foreach ($products as $product) {
            // perform action here.
        }
    });
}

Upvotes: 0

Related Questions