Skip to content

Conversation

michaelcontento
Copy link
Contributor

This PR adds the missing isEmpty() and isNotEmpty() static methods to the Str class to provide symmetry with the Stringable class methods.

Changes

  • Add Str::isEmpty($value) method
  • Add Str::isNotEmpty($value) method
  • Add tests for both methods

Motivation

Currently, Str provides various is* validation methods (isAscii, isJson, isUrl, isUuid, isUlid) but lacks isEmpty and isNotEmpty, which are available in Stringable. This creates an API inconsistency where these are the only
validation methods missing from the static interface.

Notes

This is related to #57279, as both PRs work in the same area (increasing API symmetry between Str and Stringable). However, I wasn't sure if you want to extend Str in this regard, as I can see arguments in both directions for having these two methods. I hope submitting 2 separate PRs is okay! 🙂

This adds the missing isEmpty() and isNotEmpty() static methods to the
Str class to provide symmetry with the Stringable class methods. These
are the only is* validation methods that were missing from Str.
Tests cover empty strings, whitespace, zero values, and various string
content to ensure proper validation behavior. All tests pass successfully.
@shaedrich
Copy link
Contributor

So, Str::isEmpty('') is better than '' === ''?

@michaelcontento
Copy link
Contributor Author

Fair point! Though the same argument applies to other Str methods too - Str::length($foo) vs mb_strlen($foo), Str::position() vs mb_strpos(), etc.

My goal isn't to argue that Str::isEmpty() is objectively better than native comparisons. It's about API symmetry: Str and Stringable provide the same string functionality, just with different access patterns (static methods vs fluent object). Having isEmpty/isNotEmpty available in Stringable but missing from Str feels inconsistent.

As a developer switching between both, it's confusing when the validation methods suddenly don't align. 🙂

@shaedrich
Copy link
Contributor

Fair point! Though the same argument applies to other Str methods too - Str::length($foo) vs mb_strlen($foo), Str::position() vs mb_strpos(), etc.

To a certain extent, but the difference is far smaller with your examples, where it can easily be dismissed.

My goal isn't to argue that Str::isEmpty() is objectively better than native comparisons. It's about API symmetry

Not everything needs to be just for the sake of symmetry. Especially when it is entirely nonsensical.

Str and Stringable provide the same string functionality, just with different access patterns (static methods vs fluent object). Having isEmpty/isNotEmpty available in Stringable but missing from Str feels inconsistent.

Well, there is a clear difference: A Stringable cannot directly compared to an empty string. You would have to cast it first, which makes the line already longer and the difference therefore smaller. Also, Stringable has a fluent API and the string could have been emptied by a previous method call on the object, so it makes much more sense there.

@michaelcontento
Copy link
Contributor Author

You're right that Stringable::isEmpty() has a clearer use case here since direct comparison requires casting first.

I still think the symmetry argument holds value from a DX perspective - when both classes share the same set of validation methods (isAscii, isJson, isUrl, etc.), having these two missing creates a small mental friction. But I understand if you see it differently.

I'm aware that my other PR (#57279 for Stringable::doesntContain()) is probably the stronger case for API symmetry, since Stringable::contains() exists but Stringable::doesntContain() is missing. That's why I split those two somewhat related changes into two PRs 😄

With Str::isEmpty() I can see both sides - I just wanted to highlight the inconsistency and provide a solution. But happy to close this if the Laravel team feel it's not worth adding. No hard feelings! 🙂

@shaedrich
Copy link
Contributor

shaedrich commented Oct 6, 2025

No hard feelings! 🙂

Same here! 🙂

I still think the symmetry argument holds value from a DX perspective

What's the use to have it, just to have it, but nobody uses it? Or where's the person saying "damn, what would I give to have Str::isEmpty()—I would finally be able to check if my string is empty but by having to write a whole novel. Brevity and native syntactic solutions are the death to code style. Besides, I wouldn't even know how to check if a string is empty"?

@donnysim
Copy link
Contributor

donnysim commented Oct 6, 2025

If we're to have Str::isEmpty I'd probably want it to do more than just check for === '', for example, trim the string and then check if it's empty - for me ' ' is still an empty string. At least that way it would bring value over just plain comparison.

@shaedrich
Copy link
Contributor

Yeah, that would probably more of a benefit. However, then, we would need to keep API symmetry in mind. For Stringable::isEmpty() to be changed, this would then probably go to master/13.x as this would be a potential breaking change.

@donnysim
Copy link
Contributor

donnysim commented Oct 6, 2025

I'm not sure if this warrants API symmetry, because Stringable also has whenEmpty, whenNotEmpty etc. This would change the expected output unless they also start trimming when called, whereas the Str being a standalone would not. But I can see it becoming confusing and problematic.

@taylorotwell
Copy link
Member

Thanks for your pull request to Laravel!

Unfortunately, I'm going to delay merging this code for now. To preserve our ability to adequately maintain the framework, we need to be very careful regarding the amount of code we include.

If applicable, please consider releasing your code as a package so that the community can still take advantage of your contributions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants