Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Joshuyo's avatar

How to get trimmed value via eloquent

I save blog posts in a table called "articles". Whole post is inserted in column named "content". How can I retrieve sub string of this column via eloquent?

0 likes
8 replies
Yorki's avatar

What do you want to accomplish exactly?

class Article extends Model
{
    protected $table = 'articles';
    protected $fillable = ['content'];
}
$article = Article::find(1);
$sub = substr($article->content, 0, 100);
Joshuyo's avatar

Sorry I needed to clarify one thing. Here is my code:

$records = Article::where('title', 'like', '%'.$key.'%')->get();
return response()->json(['article' => $records]);

After an ajax call, corresponding records are found and returned. Instead of sending the whole content, I would like to send the first paragraph to utilize performance.

tykus's avatar
tykus
Best Answer
Level 104

You would need to either iterate of the records in PHP, or more efficient would be to use a database function like MySQL's SUBSTRING() in your select query and limit by length rathe than paragraph:

Article::where('title', 'like', '%'.$key.'%')
    ->selectRaw('SUBSTRING(content, 1, 50) as snippet')
    ->get();

You can add extra data by chaining an addSelect('other', 'table', 'fields') to the query

1 like
Yorki's avatar

You could go like this

$records = Article::where('title', 'like', '%'.$key.'%')->get()->toArray();

foreach ($records as &$record) {    
    $record['content'] = $this->getFirstParagraph($record['content']);
}

return response()->json(['article' => $records]);
public function getFirstParagraph($content)
{
    //Depends if you have HTML with p tag or plain text with dot
    $dotPos = strpos($content, '.');

    return $dotPos !== false
        ? substr($content, 0, $dotPos)
        : $content;
}
1 like
tykus's avatar

If you wanted, you could also define an accessor on the Article model which limits the string, and appends that property by default to JSON responses:

// Article.php

protected $appends = ['snippet'];

public function getSnippetAttribute()
{
    return str_limit($this->attributes['content'], 50);
}

This accessor approach would allow you to do more work to determine where the first paragraph ends.

1 like
Yorki's avatar

You could mix @tykus solution with mine and add some extra code to achieve this

class Article extends Model
{
    ...

    protected $appends = ['paragraph'];

    protected $hidden = ['paragraph']; //by default we want content, not paragraph

    public function getParagraphAttribute()
    {
        //Depends if you have HTML with p tag or plain text with dot
        $dotPos = strpos($this->attributes['content'], '.');

        return $dotPos !== false
            ? substr($this->attributes['content'], 0, $dotPos)
            : $this->attributes['content'];
    }
}
$records = Article::where('title', 'like', '%'.$key.'%')
    ->get()
    ->makeVisible(['paragraph'])
    ->makeHidden(['content']) //to save resources
    ->toArray();

return response()->json(['article' => $records]);
1 like
martinbean's avatar

After an ajax call, corresponding records are found and returned. Instead of sending the whole content, I would like to send the first paragraph to utilize performance.

@Joshuyo Create an accessor on your Article model to do exactly that:

class Article extends Model
{
    public function getFirstParagraphAttribute()
    {
        // Get first paragraph from $this->body
    }
}

I don’t know how you’re storing the body (plain text, HTML, Markdown etc), so I’ll leave it up to you on how to extract the first paragraph from your article’s body but when you’ve done so, you can call:

$firstParagraph = $article->first_paragraph;

Succinct and self-explanatory.

2 likes

Please or to participate in this conversation.