abkrim's avatar
Level 13

Latest update of laravel broke str_contains helpers

Hi.

After update composer today i get problems with str_contains helper.

I don't know if problems is of laravel or other package needs this package.

I've tried find vendor -type f -name composer.json -exec grep -il polyfill-php80 {} ;

vendor/symfony/console/composer.json
vendor/symfony/var-dumper/composer.json
vendor/symfony/mime/composer.json
vendor/symfony/debug/composer.json
vendor/symfony/intl/composer.json
vendor/symfony/polyfill-php80/composer.json
vendor/symfony/error-handler/composer.json
vendor/symfony/http-kernel/composer.json

Error in tinker

 $s = ['servidor','softraid','fidelidad', 'recarga de cuenta de prepago']
=> [
     "servidor",
     "softraid",
     "fidelidad",
     "recarga de cuenta de prepago",
   ]
>>> str_contains('soft', $s`)
TypeError: Argument 2 passed to str_contains() must be of the type string, array given on line 1

On helpers i see

if (! function_exists('str_contains')) {
    /**
     * Determine if a given string contains a given substring.
     *
     * @param  string  $haystack
     * @param  string|array  $needles
     * @return bool
     */
    function str_contains($haystack, $needles)
    {
        return Str::contains($haystack, $needles);
    }
}

In bootstrap of symfony/pollyfil-php80 I see

if (!function_exists('str_contains')) {
    function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); }
}

But I use php 7.4.8

I'm lost.

0 likes
8 replies
chr15k's avatar
chr15k
Best Answer
Level 7

I don't think there's too much you can do about this since str_contains is deprecated as of 5.8: https://github.com/illuminate/support/blob/df4af6a32908f1d89d74348624b57e3233eea247/helpers.php#L906

The symfony/polyfill-php80 package is getting registered first, so you'll have to choose between laravel/helpers package and symfony/polyfill-php80 if you want to use str_contains

Have you considered updating all calls to the laravel/helpers methods to use the Illuminate\Support\Str and Illuminate\Support\Arr classes?

use Illuminate\Support\Str;

Str::contains('soft', $s);
1 like
chr15k's avatar

@martinbean Installing the laravel/helpers package won't fix this afaict; The symfony/polyfill-php80 str_contains method gets registered first.

1 like
martinbean's avatar

@chr15k Then @abkrim will need to replace instances of str_contains in their application with the class-based version.

1 like
abkrim's avatar
Level 13

@chr15k

Ok and thnaks for link, but on code of laravel/framework/src/Illuminate/support/helpers.php is not deprectaed

if (! function_exists('str_contains')) {
    /**
     * Determine if a given string contains a given substring.
     *
     * @param  string  $haystack
     * @param  string|array  $needles
     * @return bool
     */
    function str_contains($haystack, $needles)
    {
        return Str::contains($haystack, $needles);
    }
}

This despite me and others.

Is a old project and I'v forget changes in models helpers...

For response Str:contains is not valid, because Str::contains is for if the given string contains any of the values. And str_contains check needles string or array.

I create my own helper

/**
 * Determine if a given string contains a given substring.
 *
 * @param  string  $haystack
 * @param  string|array  $needles
 * @return bool
 */
function my_str_contains($haystack, $needles)
{
    return Str::contains($haystack, $needles);
}
martinbean's avatar

but on code of laravel/framework/src/Illuminate/support/helpers.php is not deprectaed

@abkrim What do you mean? The official Laravel documentation clearly states those functions are deprecated.

For response Str:contains is not valid, because Str::contains is for if the given string contains any of the values. And str_contains check needles string or array.

This doesn’t make any sense. You can clearly see from the code snippet you posted, that the str_contains helper function just calls Str::contains. So they do the exact same thing and have the exact same behaviour!

So, if you’ve updated your application to Laravel 6.x or Laravel 7.x, you no longer have access to the str_ helper functions and instead need to change them to their Str:: equivalents. You can do this with a simple “find all” across your project and update each usage.

abkrim's avatar
Level 13

Well. A mistake. For me, when any piece of code is deprecated, is deprecated in code and in manuals.

I read code, and I see function not deprecated. It's all.

I don't UPDATE from laravel 6. It's and app that use every trhee month for accounting. Only update, every three months.

After read you reply, i get my second mistake.

>>> $s = ['servidor','softraid','fidelidad', 'recarga de cuenta de prepago']
=> [
     "servidor",
     "softraid",
     "fidelidad",
     "recarga de cuenta de prepago",
   ]
>>> Str::contains('soft', $s)
=> false   // My second error
>>> Str::contains('softraid', $s)
=> true

I thought, instead of reading the code, that it was worth a partial search when I actually need one of the array elements to exist.

Now it is solved and corrected.

Your help is greatly appreciated.

Please or to participate in this conversation.