-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[8.x] Fix stringable implementation #37603
[8.x] Fix stringable implementation #37603
Conversation
7ad70f8
to
d0c0ad7
Compare
@lukeraymonddowning looks like string handling is broken if the person is already using ternarys. |
This caused an issue since I'm using Livewire and |
@lukeraymonddowning Any reason we are outputting ternaries in the complied view? I switched to just calling a method in the Blade compiler (since we are already resolving the compiler) instead. |
d0c0ad7
to
b2940e2
Compare
@ibrasho why make the call to the echo handler method in every compiled echo instead of only when there are actually echo handlers that are registered? |
@ibrasho ternary isn't necessary, although I think you've removed the ability for it to skip over if no handlers have been defined, which causes lots of other tests to fail |
The main reason I did that was that having different compiled outputs for echo tags was a bit confusing and made debugging hard for me. Having more consistent compiled output (regardless if the user has defined stringable handlers or not) seemed like a better idea. WDYT @taylorotwell @lukeraymonddowning? I can either fix the tests, or restore the empty handler check? |
b2940e2
to
8584050
Compare
@ibrasho I would say 2 reasons for not having logic if no handlers have been defined:
|
8584050
to
2b9301d
Compare
I'd personally prioritize maintainability over an unnoticeable performance improvement. But I'll leave that decision to @taylorotwell . I updated the commit to add the empty handlers check back. |
Thanks for the fix @ibrasho 👍 out of curiosity, how often do you find yourself debugging and reading through the compiled PHP? |
Not frequently enough to make it matter honestly. But I'd rather I don't waste any time doing that in the first place. 😁 |
@taylorotwell it looks like that change also breaks semicolons in echo statements. Is that even a supported feature that we should bring back? (Check livewire/livewire#2935) |
Could we strip out the last semicolon in the value? Can you see an issue with that? |
Just done a test and it does work. Here's a test: public function testHandlerLogicWorksCorrectlyWithSemicolon()
{
$this->expectExceptionMessage('The fluent object has been successfully handled!');
$this->compiler->stringable(Fluent::class, function ($object) {
throw new Exception('The fluent object has been successfully handled!');
});
app()->singleton('blade.compiler', function () {
return $this->compiler;
});
$exampleObject = new Fluent();
eval(
Str::of($this->compiler->compileString('{{$exampleObject;}}'))
->after('<?php')
->beforeLast('?>')
);
} And here's the updated method logic: protected function wrapInEchoHandler($value)
{
return empty($this->echoHandlers)
? $value
: 'app(\'blade.compiler\')->applyEchoHandler(' . Str::beforeLast($value, ';') . ')';
} Might be a good case for a test dataprovider, and throw it a bunch of common use cases |
I'm not sure I totally follow the semicolon issue. What is the problem? |
@taylorotwell basically if the value inside the {{ }} ends in a semicolon, it throws an error because it gets wrapped in a method call, and you can't have a semicolon in a method parameter. |
For an example, this: {{ $a; }} now compiles into: <?php echo e($a;); ?> or if a stringable is defined: <?php echo e(is_object($a;) && isset(app('blade.compiler')->echoHandlers[get_class($a;)]) ? call_user_func_array(app('blade.compiler')->echoHandlers[get_class($a;)], [$a;]) : $a;); ?> Both cause a |
I don't see any issues with doing that, but I want to make sure @taylorotwell agrees this is the way forward. |
Personally this whole feature is starting to give me a headache 😬 Is there any faster way to do this than calling into the container to resolve something on every single echo in your application's templates? That could be thousands of times per template when showing a lot of data. Calling into the container has to check for aliases, raise a before resolving event, etc. If we can't think of a clean, fast way to solve this I may just remove the feature. |
Let me take another look this evening. Might be able to resolve it once at the top of the template. I think the original issue is solved to be honest. I'm struggling to see how the semicolon issue wasn't a problem previously, since it's also broke on echos it doesn't touch. |
@taylorotwell couldn't add to this PR so opened a new one: #37613 |
2b9301d
to
65fe8fb
Compare
I just updated the |
5cdbb41
to
dd909db
Compare
@ibrasho doesn't this change how you'd declare a handler seen as the compiler no longer has the stringable method? |
dd909db
to
2527bed
Compare
I made a simple change to add that method back to BladeCompiler. |
2527bed
to
52c393f
Compare
Fixed. Thanks. |
The current implementation compiles echo statements with ternary operators (e.g.
{{ $test ? "1" : "2" }}
to the following code which throws aFatalError
on PHP 8:This PR tries to fix that issue by generating a compiled view without an included ternary operator.