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

spaceemotion's avatar

PHP's "compact" - Pros and cons

I was looking through some code the other day and saw yet another laravel library / project that used "compact" almost everywhere when it was sending data over to the view.

My question is: What are the pros and cons of using compact in the following situation? Isn't it just faster to use the variables directly?

public function index($id)
    {
        $category = Category::find($id);
        $topics = $category->getTopicPaginator();
        $message = Message::find(1);

        // here I would just use "->with([$category, $topics, $message])"
        return View::make('category.index')->with(compact('category', 'topics', 'message'));
    }

Thanks in advance!

0 likes
13 replies
JoshWilley's avatar

I feel like that's a bit of a pre-mature optimization question. I don't think you'll find any performance gains by using any of the methods available, over another.

This really comes down to readability and what makes the most sense when glancing at the code.

Personally, I don't like any of the methods that people use 99% of the time (with, compact, etc.)

Laravel's View::make() method accepts a second parameter to pass variables through.

I find this is a lot more readable than any of the other solutions:

public function index($id)
    {
        $data['category'] = Category::find($id);
        $data['topics'] = $category->getTopicPaginator();
        $data['message'] = Message::find(1);

        return View::make('category.index', $data);
    }
8 likes
austenc's avatar

I typically don't use compact myself, but it allows a bit of shorthand versus:

public function index($id)
    {
        $category = Category::find($id);
        $topics = $category->getTopicPaginator();
        $message = Message::find(1);

        // here I would just use "->with([$category, $topics, $message])"
        return View::make('category.index')->with([
            'category' => $category,
            'topics' => $topics,
            'message' => $message,
        ]);
    }
2 likes
daveyoi's avatar

Agree with @JoshWilley 100% - Maybe its a hangover from my CI days - or just MVC in general - but a lot of the Laravel helpers for passing data into a view seem like overkill to me.

5 likes
JoshWilley's avatar

@daveyoi - It's funny you say that because I've never worked with CI at all. When I first started working with Laravel, the way documentation and tutorials showed how to pass data to a view bugged me. I was thinking.. "There HAS to be a cleaner way".

I actually wrote a view composer a while back that did a bunch of stuff to allow me to pass the data through to the view like above.

And then randomly, I started refactoring, completely got rid of the view composer and it still worked! It was a sort of love-hate thing because I had worked so hard on this view composer, however, the functionality was already built into Laravel. Haha.

1 like
spaceemotion's avatar

@daveyoi - coming from CI myself I also can relate with that. I quite like the freedom of laravel though (You can use the array or the withKey($value) syntax). I personally use my suggested method as stated the first post, but I guess it really is just personal preference.

I just wanted to know if there'd be significant differences in speed, etc. ;)

alexhiggins's avatar

I don't like compact either. Usually i'll do something like

return View::make('thread.index')->with([
  'article' => $this->articleRepo->getArticleFromSlug($slug)
]);

Or like @austenc example depending on the situation

JeffreyWay's avatar

I have no problem with using compact(). It's quick and easy. And if you ultimately need to change it up...well that takes five seconds.

return view('posts.index', compact('posts', 'tags'));
18 likes
phenocode's avatar

I like how clean and concise compact is. I don't end up having to type the variable name multiple times, and it prevents me from using variables names that aren't really what they should be.

outboundexplorer's avatar

When looking at compact() here are some notes that i use to refresh my memory :)

method 1

public function index()
{
        $sortBy = Request::get('sortBy');
        $direction = Request::get('direction');
        $users = $this->userRepository->getPaginated(['sortBy' => $sortBy,'direction' => $direction]);
        return View::make('users.index')->with(['users' => $users, 'sortBy' => $sortBy, 'direction' => $direction]);
}

method 2

public function index()
{
       $data['sortBy'] = Request::get('sortBy');
       $data['direction'] = Request::get('direction');
       $users = $this->userRepository->getPaginated($data);
        return View::make('users.index')->with(['users' => $users, 'sortBy' => $sortBy, 'direction' => $direction]);
}

method 3 - using compact()

public function index()
{
        $sortBy = Request::get('sortBy');
        $direction = Request::get('direction');
        $users = $this->userRepository->getPaginated(compact('sortBy','direction'));
        return View::make('users.index')->with(compact('users','sortBy','direction'));
}

Hope someone finds this useful!!

1 like
narfed's avatar

@outboundexplorer How about this for method 2?

public function index()
{
       $data['sortBy'] = Request::get('sortBy');
       $data['direction'] = Request::get('direction');
       $data['users'] = $this->userRepository->getPaginated($data);
        return View::make('users.index', $data);
}
6 likes
cshelswell's avatar

@narfed That's the solution i've always used it seems to work well for me and saves defining vars twice.

2 likes

Please or to participate in this conversation.