Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Result of a method call on Eloquent\Builder depends on the method casing used #48825

Closed
luka-papez opened this issue Oct 26, 2023 · 6 comments · Fixed by #48852
Closed

Result of a method call on Eloquent\Builder depends on the method casing used #48825

luka-papez opened this issue Oct 26, 2023 · 6 comments · Fixed by #48852

Comments

@luka-papez
Copy link
Contributor

luka-papez commented Oct 26, 2023

Laravel Version

10.29.0

PHP Version

8.1.2

Database Driver & Version

Not relevant but just in case: psql (PostgreSQL) 14.9 (Ubuntu 14.9-0ubuntu0.22.04.1)

Description

When calling a method on a instance of Eloquent\Builder, the result of the method will depend on the method casing used. I discovered this when I called $query->toSQL() instead of $query->toSql() and got back a Builder instead of a string which I expected. Given that PHP is case-insensitive about method names, I find this behavior surprising.

According to my understanding, the issue happens on this line:

The Builder decides what to do with the result depending on whether the called method is found in the $passthru property. Since toSql is there, and toSQL is not, the result is different.

I believe the behavior could be fixed by lowercasing the method name and making the $passthru property contain lowercased method names, but I am not sure what kind of implications that might have down the road.

If needed, I would be happy to volunteer some time into fixing this issue, or reviewing the fix. Either way, thank you for all the hard work on making Laravel so great for the rest of us!

Steps To Reproduce

The behavior can be triggered by the following snippet:

        $query = User::query()->select('*');

        $camelCaseResult = $query->toSql();  // this returns a string
        $upperCaseResult = $query->toSQL();  // this returns $query

A small repository demonstrating this behavior can be found here:

It's based on the example Laravel app with a separate commit demonstrating the potential problem

@driesvints
Copy link
Member

We'd welcome PRs for this 👍 thanks!

@github-actions
Copy link

Thank you for reporting this issue!

As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.

If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.

Thank you!

@Guxinpei
Copy link

I've come across the same issue, and I appreciate you bringing this up and suggesting a fix by modifying the case. While this proposal may address the problem at hand, I believe employing a pipeline to manage the __call method's multiple priority processes could provide a more structured and robust solution, ensuring that casing discrepancies don’t affect functionality. This approach might also be more adaptable to other similar issues that could arise in the future. Just a thought!

@luka-papez
Copy link
Contributor Author

@driesvints I went ahead and implemented a fix in: #48852
Any feedback is very welcome!

@luka-papez
Copy link
Contributor Author

@Guxinpei While I agree that the current method dispatch could be made more robust, I am not sure if the added complexity would really be worth it.

Eloquent\Builder is such a widely used class, and yet it still took me many moons of using Laravel to stumble across this problem (in fact a student of mine pointed it out, classing "rookie mistake" 🙂 )

luka-papez added a commit to luka-papez/laravel that referenced this issue Oct 29, 2023
luka-papez added a commit to luka-papez/laravel that referenced this issue Oct 29, 2023
luka-papez added a commit to luka-papez/laravel that referenced this issue Oct 29, 2023
luka-papez added a commit to luka-papez/laravel that referenced this issue Oct 29, 2023
taylorotwell added a commit that referenced this issue Oct 29, 2023
…ould be case-insensitive (#48852)

* fix(Eloquent/Builder): calling the methods on passthru base object should be case-insensitive

Fixes: #48825

* Update Builder.php

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
taylorotwell added a commit to illuminate/database that referenced this issue Oct 29, 2023
…ould be case-insensitive (#48852)

* fix(Eloquent/Builder): calling the methods on passthru base object should be case-insensitive

Fixes: laravel/framework#48825

* Update Builder.php

---------

Co-authored-by: Taylor Otwell <taylor@laravel.com>
@bertoost
Copy link

Any existing $passthru lists with correct casing will be broken with this update. See my comment on the PR #48852

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants