We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Too many negative votes

This post has too many negative votes. The cause of this could be:

  • Irrelevant or controversial information
  • Confusing question or not a real question
  • Aggressive vocabulary, excessive rudeness, etc

Mixing Laravel with Phalcon

After a few tries with Phalcon raw query, phpl and orm, I'm about to give up on Phalcon. It's too hard to do any serious database query in Phalcon.

The ORM Model is useless because I'd like to join tables with complex conditions. The has_many_through hasn't yet been implemented. And I don't even know if it can do eager loading either.

Phpl and raw query? why I must to paste some length and hard to maintain string instead of this:

join('thread_tag', 'threads.id', '=', 'thread_tag.thread_id')
        ->join('tags', 'tags.id', '=', 'thread_tag.tag_id')
    ->where('tags.name', 'in', DB::raw(static::wrap_tag($tags)))
    ->group_by('threads.id')
    ->having(DB::raw('count(tags.id)'), '=', count($tags))
    ->order_by('threads.updated_at', 'desc')
    ->take($limit)
    ->skip($offset)
    ->get([DB::raw('threads.*')]);

and most of all, because of the N+1 problem, I have to deal with eager loading myself (when laravel offers it nicely).

It would be best if I can use Laravel library inside of Phalcon. It can be done, right? Then we could have both: the speed of Phalcon and the easy-of-use of Laravel.

p/s: admitted, I'd rather static method call like DB::raw(), Session::get(), Input::get() to \Phalcon\Db\RawValue('default') , $this->session->getVar(), $this->request->getPost() and all...

Maybe I should write helper class using shortcut call to actual phalcon methods. Because I don't use code completion, having short and easy to type and remember method is ways better.

You not using code completion is hardly Phalcon's problem, no? But I don't understand what the actual problem here is, I use raw queries all the time. Just get the DB connection and execute a query on it. Or do I misunderstand the problem? Are you bothered by having to write string queries specifically? Because you can eager load by writing regular queries and avoiding Phalcon's ORM altogether, you don't have to use anything you don't want to. Many of my services execute pure complex DB queries against the database, bypassing the ORM and PhalconQL completely.

Anyway, you can use Laraver with Phalcon, sure, but why? You say "speed of Phalcon and easy-of-use of Laravel", but you don't get speed of Phalcon if you use Laravel with Phalcon, you get speed of Laravel, because Laravel doesn't invoke any Phalcon functions, it uses PHP as usual.



98.9k

Same query in Phalcon:

$query = $this->modelsManager->
    ->createBuilder()
    ->from('Tags')
    ->join('ThreadTag', 'Threads.id = ThreadTag.thread_id')
    ->join('Tags', 'Tags.id = ThreadTag.tag_id')
    ->whereIn('Tags.name', static::wrap_tag($tags)) //?
    ->groupBy('Threads.id')
    ->having('count(Tags.id) = ' .count($tags))
    ->orderBy('Threads.updated_at desc')
    ->limit($limit, $offset)  
    ->columns('Threads.*')
    ->getQuery();


4.8k

@Bruno Škvorc: you see, in Laravel eager loading is done automatically for me. So when I want to display a list of threads, which one have an author (users.username), and a list of tags (insides tags table with table thread_tag as pilot) I can easily do thing like this

foreach ($threads as $thread) {
    echo $thread->user->username();
    echo $thread->title();
    foreach ($thread->tags as $tag) {
        echo $tag.name;
    }
}

all of this requires only 3 queries, insteads of 2 * N + 1 query if you do not use eager loading.

@Phalcon: I know Phalcon can do chain query too, but then the result wont be Thread objects anymore, right. See my full function and you will understand my point:

public static function fetch($offset = 0, $tags = NULL, $limit = Thread::limit, $order_by = THREAD::lastbump) 
    {
        switch(gettype($tags))
        {
            case "NULL":
                return static::take($limit)
                ->skip($offset)
                ->order_by(DB::raw($order_by), "")
                ->get();
            break;

            case "string":
                return static::join('thread_tag', 'threads.id', '=', 'thread_tag.thread_id')
                ->join('tags', 'tags.id', '=', 'thread_tag.tag_id')
                ->where('tags.name', '=', $tags)
                ->order_by(DB::raw($order_by), "")
                ->take($limit)
                ->skip($offset)
                ->get([DB::raw('threads.*')]);
            break;

            case "array":
                return static::join('thread_tag', 'threads.id', '=', 'thread_tag.thread_id')
                ->join('tags', 'tags.id', '=', 'thread_tag.tag_id')
                ->where('tags.name', 'in', DB::raw(static::wrap_tag($tags)))
                ->group_by('threads.id')
                ->having(DB::raw('count(tags.id)'), '=', count($tags))
                ->order_by(DB::raw($order_by), "")
                ->take($limit)
                ->skip($offset)
                ->get([DB::raw('threads.*')]);
            break;
        }
    }

all though it's different queries, the result is the same type. I believe it's not the case in Phalcon.

Btw, It's nice to have some speed, but productivity is much more important I think. Heck, I could use openresty if I want to, and scripting is not a matter since it's using lua. Also, check out lapis: https://leafo.net/lapis/ It looks promising (still lack a lot to be a full fledged framework though)

In Laravel, the name convention is so easily to remember that I don't have to check the documents and api every time just because I keep forgot the name (I don't use an IDE). Every time I read a phalcon source codes, my head hurts (yes I check a lot, vokuro, phalconeye, invo, album-o-rama, phalconforum, mvc... each one has a difference code style, a lot of code that's just too hard to understand as first glare). After a week and in Phalcon and I'm still finding myself changing the configurations. And that's not a good thing. Let's say Phalcon just is not designed for a novice like me to use.

Btw, I installed openresty moonscript and lapis, and nginx always threw out an error "permission denied access web.lua" even though I chmod 777 the whole folder. Heck, even in nginx I'm a noob too. Still can't figure out the case.



98.9k

Ease of use is very subjective, tools/frameworks that I know are more productive (to me) than the tools I'm just learning or I'm not familiar with, we're always going to feel more confortable/productive with tools/syntaxes that we already known because that is the human nature. So, this is not a problem related with Phalcon or with any other tool. I like linux and when I work on Windows I feel less productive, Is Windows less easier than Linux? I don't think so.

Since, Phalcon could implement similar ideas or features that other frameworks already have, and we're not interested in reinventing the wheel, the real fact is that Phalcon is not a port in C of framework "X", it's a full brand new framework that must be understood as its design and philosophy.

Phalcon is about power, maybe you don't have realized it, but in Laravel, you're using a table data gateway/active record (https://martinfowler.com/eaaCatalog/tableDataGateway.html) , which is a set of tools that make easier write SQL, or write them using an OO syntax, but these approaches are actually less powerful and flexible.

PHQL (as DQL/HQL/NQL) etc, are high level query languages which allow you to work with objects/classes using an structured language, which is something that a real ORM must provide. You have an additional layer that allow you to change your database (design or vendor) without affecting your application, and the better thing is that it is fast!

As PHQL is an object-oriented language, this return Threads objects:

->columns('Threads.*') // give me instances of class Threads

while in Laravel (I can't understand why write >get([DB::raw('threads.*')]) is easier) you're saying:

>get([DB::raw('threads.*')]) // give me rows of table threads

So, there is a BIG difference in what you're writing, you're mixing direct SQL (implicitly) with OO programming, while in Phalcon everything is OO.



4.8k

@phalcon

->get([DB::raw('threads.*')]) // give me instances of class Threads

I was adding that because of some laravel bug that would not display the tags correctly using eager loading. Not because doing that would make the result a Thread row. By default in laravel every thing pass to a model or a query is escaped, therefore I have to wrap DB::raw() to ensure it's always left untouched.

Yeah you are right about Phalcon is fully OO. I tried to var_dump a resultset and the output is... enormous. Some time I just wish to grab some data from the server, and done with it.

The syntax is just a matter of taste, I know.

And the most important point of this, is that with phalcon I can't seam to have a list of threads, include their author (author name is in users table) and each list of tags that associate with one thread just by doing three queries call. Or it can?

You can say about all about the speed and oo with phpl and orm you want, but not before the orm has many to many relation support, and preloading the result, I would rather go with a slower framework that supports it well I think.

And btw, I'm not asking you to make a copy of another framework, but rather wrap around aliases that's easy to call and remember.

I know that this framework is still young and has a lot of space to improvement, but adding a little more of user friendliness will always be a good thing.

I know you have your own philosophy about the framework, but check out and learn good things from the other frameworks will make it more usable. The way I like about laravel is that everything I need just be there for me to use, even a profiler. And the richness of bundles is appealing.

As I recalled, somebody in this forum mentioned that it's better to only write crucial parts in C (route, controller, model...) and the unimportant parts in php would be better. Make it highly integratable with external library would be good, too.

Just my suggestion though.

edited Aug '14

A couple of points if I may

Yeah you are right about Phalcon is fully OO. I tried to var_dump a resultset and the output is... enormous. Some time I just wish to grab some data from the server, and done with it.

Try Doctrine. Then you will see what an enormous resultset is about :).

You can say about all about the speed and oo with phpl and orm you want, but not before the orm has many to many relation support, and preloading the result, I would rather go with a slower framework that supports it well I think.

As discussed before you can write pure SQL. So that in effect is your many to many support. Granted it is not a pure OO design but it will get you what you want. In the meantime that feature is already under development so if you want to wait, fine again.

And btw, I'm not asking you to make a copy of another framework, but rather wrap around aliases that's easy to call and remember.

What is the point of this? If you are going to use framework A, why mix it with framework B? You either use Phalcon or not. Phalcon is not Laravel and Laravel is not Phalcon. Simple as that. If you really really want to mix the two then I can assure you will end up with a lot of spaghetti code. If you want in your application to have aliases so that you can remember things better, extending the Model class for instance will allow you to use a get, fetch, gimmesomelovin or whatever function name you want to wrap functionality around.

I know that this framework is still young and has a lot of space to improvement, but adding a little more of user friendliness will always be a good thing.

Static methods (to borrow your example above) is not user friendliness. It is a pain in the behind. Static methods are not easily testable and I definitely want to inconvenience a developer this much than give them something that cannot be tested easily and will potentially lead to bugs in the future with their application. Also friendliness depends on how you see things from your own prism as a developer. I might say that this is not user friendly you might say otherwise. We have always tried to keep a good balance between functionality and ease of use. That attitude will not change. If a particular function can be shortened and an alias created, we are all for it. All that has to be done is a Github issue as a NFR and the community to approve of it with their votes.

I know you have your own philosophy about the framework, but check out and learn good things from the other frameworks will make it more usable.

That is your opinion. My experience has been totally different in terms of usability. At this moment in time Phalcon has very little to "learn" from other frameworks if any.

The way I like about laravel is that everything I need just be there for me to use, even a profiler. And the richness of bundles is appealing.

Why do you post here then? If Laravel has everything you need just use that. I get really annoyed when people turn around and want to switch Phalcon to something else. Phalcon is its own framework and has functionality A. Laravel has functionality B. In some instances those two are common and in some they are not. It is a huge mistake to want to change a framework so that it abides with what you are used to. I am curious if people have turned around and told Zend to follow Laravel's or Fuel's approach (just picking two in random here).

If people love Laravel so much and want the speed of Phalcon, maybe we can all create a new github repository where the new Pharavel will be created, Laravel in C....

Everyone get VIM ready, we are going C hunting.