Skip to content

Patch add str begins and ends #2049

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

Closed

Conversation

wkhudgins92
Copy link
Contributor

This is the patch for RFC
https://wiki.php.net/rfc/add_str_begin_and_end_functions

This PR contains the implementations of str_begins() and str_ends() and also the phpt tests.

@wkhudgins92
Copy link
Contributor Author

Not sure what the build failure is about. I was able to compile this on my local machine using make -j2 and I was able to run the compiled PHP and also execute make test.

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SS|l", &str, &search_value, &case_sensitive) == FAILURE)
RETURN_NULL();

for (int i = 0; i < search_value->len; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The int i should go to the top of the function. That should fix the build issue.

@laruence
Copy link
Member

laruence commented Aug 2, 2016

how does str_begins different from strncmp/strncasecmp?

<?php
$str = "bEginningMiddleEnd";

var_dump(strcmp($str, "bEg", 3));
var_dump(strncasecmp($str, "beg", 3));

@laruence
Copy link
Member

laruence commented Aug 2, 2016

and how does str_begins and str_ends better than substr_compare?

<?php
$str = "bEginningMiddleEnd";

var_dump(substr_compare($str, "End", -3));
var_dump(substr_compare($str, "end", -3, 3, true));
?>

@ju1ius
Copy link
Contributor

ju1ius commented Aug 4, 2016

how does str_begins different from strncmp/strncasecmp?
and how does str_begins and str_ends better than substr_compare?

Without getting into micro-optimization,

str_ends($str, $end);

is easier to write but more importantly a lot easier to read than

substr_compare($str, $end, -strlen($end), strlen($end), true);

Just from the name of it anybody should understand what it does without having to check the documentation.

@wkhudgins92 It would have been even better to name them str_endswith() and str_startswith(), which read like: «Does this string starts with this other string?», whereas str_ends sounds more like «Does this string ends?».
My $0.2

@staabm
Copy link
Contributor

staabm commented Aug 4, 2016

IMO this can easily be achieved in userland with a simple function.

@ju1ius
Copy link
Contributor

ju1ius commented Aug 4, 2016

IMO this can easily be achieved in userland with a simple function.

@staabm Of course !

But this is a so common task that most programming languages have their native implementations:

@cmb69
Copy link
Member

cmb69 commented Aug 8, 2016

It would have been even better to name them str_endswith() and str_startswith(), […]

I would fully agree, if these were methods of a string object ($str->startsWith('foo') reads so fine), but it appears to be confusing for functions: str_startswith($str, 'foo') or str_startwith('foo', $str) :-/

@nikic
Copy link
Member

nikic commented Aug 8, 2016

Not sure I see the "functions" issue. "startswith" still imposes an ordering, that the first arg startswith the second arg. Unlike just "starts" which would imply the reverse argument order (first arg starts second arg).

@cmb69
Copy link
Member

cmb69 commented Aug 8, 2016

@nikic Haskell appears to differ. :-)

@nikic
Copy link
Member

nikic commented Aug 8, 2016

Heh. It kinda does make sense to invert the argument order in Haskell in particular, because this makes partial application more useful...

@cmb69
Copy link
Member

cmb69 commented Aug 8, 2016

Yes, that makes particular sense for Haskell (and other functional languages), but they could have called it startsthen.

@brzuchal
Copy link
Contributor

brzuchal commented Aug 8, 2016

There are already such implementations based on @nikic extension in here https://github.com/rossriley/php-scalar-objects#startswith scalar objects in PHP would be awesome feature, would love to have it in core. Great job on this extension from @nikic

@ju1ius
Copy link
Contributor

ju1ius commented Aug 8, 2016

but they could have called it starts then.

But they didn't. 😉

Wrt the order of arguments, as @nikic said, you're either in an OO-like language (or library, like glib/gobject) and you expect $this to be the first argument, or a functional-like language (or library) and you expect the data to be operated on to be the last argument. Both make perfect sense and it's not confusing as long as the api is consistent throughout the library.

Which raises the infamous issue:

function array_filter(array $array, callable $callback): array;
function array_map(callable $callback, array $array): array;

deserving a RFC on it's own ! 😆

@wkhudgins92
Copy link
Contributor Author

wkhudgins92 commented Aug 13, 2016

Edited the code and modified the RFC (https://wiki.php.net/rfc/add_str_begin_and_end_functions) to reflect the comments brought up here and in the mailing list.

I split the functions into separate functions based on case sensitivity and switched the order of $str and $seach_value to be consistent with the other str_* functions. I also switched from _begins() and _ends() to the singular _begin() and _end(). In addition, the requested changes now pass the Travis CI tests.

@nikic nikic added the RFC label Aug 15, 2016
@ChadSikorra
Copy link
Contributor

Will these have mb_* equivalents?

RETURN_NULL();

for (i = 0; i < search_value->len; i++)
if (str->val[i] != search_value->val[i])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the length of search_value is greater than str, maybe it will access out of bounds?

Copy link
Contributor

@blar blar Sep 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you change the the interface to bool str_begin(string $haytstack, $needle) and bool str_ends(string $haystack, string $needle) for consistency with other string function like stristr, strpos, strrchr?

@eddy8
Copy link

eddy8 commented Dec 16, 2016

support~

@wkhudgins92 wkhudgins92 force-pushed the patch-add-str_begins-and-ends branch from 7fc90b6 to 10205e8 Compare June 22, 2019 16:38
@@ -2581,6 +2609,192 @@ PHP_FUNCTION(mb_strripos)
}
/* }}} */

/* {{{ proto boolean mb_str_begins(string haystack, string needle [, string encoding])
Checks if haystack begins with needle */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Checks if haystack begins with needle */
Checks if haystack begins with a needle */

@azjezz
Copy link

azjezz commented Jun 22, 2019

Thanks for working on this 👍

It would have been even better to name them str_endswith() and str_startswith()

i quite agree with this ( or str_starts_with / str_ends_with instead ? ), but maybe that's just because I'm more familiar with hack standard library. ( HH\Lib\Str\starts_with(_ci) / HH\Lib\Str\ends_with(_ci) )

@theodorejb
Copy link
Contributor

Is this RFC going to vote before the deadline for PHP 7.4 in a few days?

@wkhudgins92
Copy link
Contributor Author

@theodorejb Yesterday marked 2 weeks of discussion, so I plan to move the RFC to a vote.

@wkhudgins92
Copy link
Contributor Author

The RFC related to this has gone to a vote: https://wiki.php.net/rfc/add_str_begin_and_end_functions

@nikic nikic added this to the PHP 7.4 milestone Jul 5, 2019
@ElvenSpellmaker
Copy link

Does anyone know why the mb_* functions are being voted against in the poll? 🤔

@nikic nikic removed this from the PHP 7.4 milestone Jul 22, 2019
@nikic
Copy link
Member

nikic commented Jan 10, 2020

The RFC was unfortunately :( :( :( declined, so I'm closing this PR.

@nikic nikic closed this Jan 10, 2020
@ElvenSpellmaker
Copy link

That's mad... All thanks to the silly 2/3 thing is seems. >50% is a majority, when will people realise that 😂 =|

@glensc
Copy link
Contributor

glensc commented Jan 22, 2020

the plain string vs mbstring vote difference seems stupid. probably shouldn't even have the opportunity to vote separately.

however, I'm personally looking for Symfony 5 string component:

@simivar
Copy link

simivar commented Mar 19, 2020

So... is there any possibility to redo the voting and add those functions together with str_contains? It’s the same family. :/

@wkhudgins92
Copy link
Contributor Author

wkhudgins92 commented Mar 25, 2020

So... is there any possibility to redo the voting and add those functions together with str_contains? It’s the same family. :/

I am going to re-raise the RFC+PR for only str_starts_with() and str_ends_with() @simivar

@glensc
Copy link
Contributor

glensc commented Mar 26, 2020

otoh, maybe instead of adding two sets of functions, add support for substring operators on the language level, like in Python (and Ruby?) do:

  • $string[-2] = substring last two elements
  • $string[:2] = substring first two elements
  • $string[2:4] = substring from offsets 2 to 4

but this can't be done until the $string can be declared as ByteArray or UnicodeString, or maybe add also object support to have custom slicers support like ArrayAcess interface exists to emulate arrays on onjects.

@guilliamxavier
Copy link
Contributor

@glensc: The "slice" syntactic sugar idea (which I have already seen proposed elsewhere BTW) is IMHO orthogonal to thoses functions (which are not implemented as $needle === substr($haystack, ...))

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

Successfully merging this pull request may close these issues.