What does the `str_contains()` function do in PHP 8.1?
PHP

What does the `str_contains()` function do in PHP 8.1?

Symfony Certification Exam

Expert Author

October 1, 20236 min read
PHPSymfonyPHP 8.1PHP DevelopmentWeb DevelopmentSymfony Certification

What does the str_contains() function do in PHP 8.1?

In PHP 8.1, the introduction of the str_contains() function marks a pivotal enhancement for developers working with string manipulations. As a Symfony developer preparing for the certification exam, understanding the str_contains() function is crucial for optimizing your code and adhering to modern PHP practices. This blog post will delve into the mechanics of str_contains(), practical examples in Symfony applications, and its implications for your development workflow.

What is str_contains()?

The str_contains() function checks if a given substring exists within a string. It returns a boolean value: true if the substring is found and false otherwise. This function simplifies string search operations, enhancing code readability and maintainability.

Syntax

The syntax for str_contains() is straightforward:

bool str_contains(string $haystack, string $needle);
  • $haystack: The string to search within.
  • $needle: The substring to search for.

Example Usage

Here's a simple example of how str_contains() works:

$sentence = "Symfony is a PHP framework.";
$word = "PHP";

if (str_contains($sentence, $word)) {
    echo "The sentence contains the word '{$word}'.";
} else {
    echo "The word '{$word}' is not found in the sentence.";
}

In this example, str_contains() checks if the word "PHP" is present in the sentence, returning true.

Why is str_contains() Important for Symfony Developers?

As a Symfony developer, utilizing str_contains() can significantly improve code clarity, especially when dealing with conditions in services, logic within Twig templates, or constructing Doctrine DQL queries. Before PHP 8.1, developers often relied on functions like strpos() to perform similar checks, which required additional logic to handle results correctly.

Advantages Over Traditional Methods

  • Readability: str_contains() clearly expresses intent, making the code easier to read and understand.
  • Simplicity: The function eliminates the need for additional checks that were necessary with strpos(), as it directly returns a boolean.
  • Performance: While performance differences may be minimal for small strings, str_contains() is optimized for common cases, enhancing overall code efficiency.

Practical Applications in Symfony

1. Complex Conditions in Services

When working in Symfony services, you may encounter scenarios where you need to check for specific substrings in configuration values, user input, or other strings. Consider the following service that validates user roles based on their permissions:

namespace App\Service;

class UserRoleService
{
    public function hasPermission(string $userRole, string $permission): bool
    {
        // Check if the user's role contains the required permission
        return str_contains($userRole, $permission);
    }
}

// Usage
$service = new UserRoleService();
$userRole = 'ROLE_ADMIN,ROLE_USER';

if ($service->hasPermission($userRole, 'ROLE_ADMIN')) {
    echo "User has admin permissions.";
} else {
    echo "User does not have admin permissions.";
}

In this example, str_contains() checks if the user's roles string contains the specified permission. This approach is straightforward and effectively communicates the purpose of the check.

2. Logic within Twig Templates

Twig templates allow you to embed PHP logic directly. Using str_contains() enhances readability when checking for substrings in template variables. Here’s an example:

{% set message = "Welcome to Symfony!" %}
{% if str_contains(message, 'Symfony') %}
    <p>The message mentions Symfony.</p>
{% endif %}

This Twig snippet uses str_contains() to determine if the message variable includes the word "Symfony". This logic is clear and easy to follow, improving template maintainability.

3. Building Doctrine DQL Queries

Integrating str_contains() into Doctrine DQL queries can simplify conditions when filtering results based on substring matches. However, as of PHP 8.1, you cannot directly use str_contains() in DQL. Instead, you can use native SQL functions or create a custom DQL function that utilizes str_contains().

For example, if you want to filter users based on their email addresses containing a specific domain, you can use the following approach:

use Doctrine\ORM\EntityManagerInterface;

class UserRepository
{
    private EntityManagerInterface $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function findUsersByEmailDomain(string $domain)
    {
        return $this->entityManager->createQuery(
            'SELECT u FROM App\Entity\User u WHERE u.email LIKE :domain'
        )
        ->setParameter('domain', '%' . $domain . '%')
        ->getResult();
    }
}

// Usage
$userRepo = new UserRepository($entityManager);
$users = $userRepo->findUsersByEmailDomain('example.com');

Here, we use a LIKE query to find users with email addresses that contain the specified domain. While this doesn’t leverage str_contains() directly in DQL, understanding its utility in PHP can help you formulate better queries.

Performance Considerations

When using str_contains(), it’s essential to consider the performance implications, especially in scenarios where string searches occur frequently or on large datasets. While str_contains() is efficient, always evaluate its usage in performance-critical paths, such as loops or high-frequency functions.

Benchmarking Example

To illustrate the performance of str_contains() versus strpos(), consider the following benchmarking code:

$haystack = str_repeat('Hello World! ', 1000); // Large string
$needle = 'World';

$startStrContains = microtime(true);
for ($i = 0; $i < 100000; $i++) {
    str_contains($haystack, $needle);
}
$timeStrContains = microtime(true) - $startStrContains;

$startStrpos = microtime(true);
for ($i = 0; $i < 100000; $i++) {
    strpos($haystack, $needle) !== false;
}
$timeStrpos = microtime(true) - $startStrpos;

echo "str_contains() time: {$timeStrContains} seconds\n";
echo "strpos() time: {$timeStrpos} seconds\n";

This example benchmarks the execution time of both functions. In most cases, you will find that str_contains() is comparable or slightly faster due to its simplicity and reduced overhead.

Best Practices for Using str_contains()

  1. Use for Readability: Favor str_contains() over strpos() when the intent is to check for the existence of a substring. This enhances code clarity.
  2. Combine with Other String Functions: Use str_contains() in conjunction with other string functions like strtolower() or trim() for more robust checks, especially when dealing with user input.
  3. Avoid Overuse in Loops: When performing multiple checks within a loop, consider caching results or using alternative logic to minimize performance impacts.
  4. Document Your Code: Even though str_contains() is self-explanatory, providing comments that explain the purpose of the check can aid future developers or your future self.

Conclusion

The introduction of the str_contains() function in PHP 8.1 significantly enhances string handling capabilities for Symfony developers. By simplifying substring checks, it promotes cleaner, more maintainable code across various application components. Whether you’re validating user roles, embedding logic in Twig templates, or building DQL queries, str_contains() proves to be a valuable tool in your development toolkit.

As you prepare for your Symfony certification exam, ensure you understand how to leverage str_contains() effectively in your projects. Embrace its benefits for readability, simplicity, and performance, and incorporate it into your coding practices to enhance your Symfony applications. Happy coding!