5 ms·
Three string functions every PHP project needs
- Nycto 15y agoFor anyone interested, you can actually make the startsWith and endsWith methods a lot faster by using strncasecmp or substr, like this: https://github.com/Nycto/Round-Eights/blob/master/src/functions/strings.php#L319 https://github.com/Nycto/Round-Eights/blob/master/src/functi... It could be a micro-optimization, but I find myself using these methods quite and it's a simple tweak to make.
- birken 15y agoThe string slicing would have been a lot more efficient had PHP accepted my patch to add this into the PHP core functions :) --> http://bugs.php.net/bug.php?id=54387 http://bugs.php.net/bug.php?id=54387 In general though we just use these around the code base for general use, and efficiency isn't a concern.
- deleted 15y ago[deleted]
- benologist 15y agoI love StartsWith, EndsWith and also Contains in C#. Contains especially feels so nice to use compared to IndexOf all the time.
- michaelcampbell 15y agoIndeed. As a Java guy, I was a bit surprised ruby's default library didn't have them (when I started with ruby, anyway; way pre-rails; it might now). Trivial to implement, but still.
- nikz 15y agoMay be slightly off-topic, but I feel a little pain behind my eyes whenever I see the hack-around-namespaces function naming (e.g tt_whatever, for "ThumbTack" presumably). Surely a singleton class would be a nicer way to do this (or just leave the "tt_" off, why is it necessary, you're not overriding core functions)?
- birken 15y agoWe actually had a debate in our engineering dept about how we wanted to handle functions like this, and in the end decided on tt_function_name() in the global function space. We decided against putting them in explicit namespaces, because we felt these were convenience functions and they should be convenient to use. We felt the convenience of: if (tt_str_startswith($url, 'https://) https://)) { } over something like: if (tt/global/string/starts_with($url, 'https://) https://)) { } was worth the lack of organization. We have <10 of these types of global functions in our code base and we are very careful about adding new ones. All other classes and functions are either in a namespace or class context. We went with the tt_ prefix because we wanted to cover our bases and really explicitly ensure we never will collide with a PHP function, and we felt it isn't too unwieldy. As for using a singleton class, since 5.3 we prefer to use namespaces instead.
- wvenable 15y agoIsn't this what use is for? use tt\global\string; if (string\starts_with($url, 'https://)) { }
- birken 15y agoSure is, and we do organize our 'use' statements the same way one would organize 'import' statements in a python file. However in this context again we felt that the convenience of just being able to throw these functions in place without having to worry about putting the proper use statement was worth the tradeoff.
- dstein 15y agoIn JavaScript I always use: String.prototype.startsWith = function(s) { return this.substring(0,s.length)===s; }; String.prototype.endsWith = function(s) { return this.substring(this.length-s.length)===s; };
- rudiger 15y agoWhat's the current consensus on augmentation of built-in prototypes [1]? Is it still a contentious issue? [1] http://michaux.ca/articles/javascript-the-good-parts-built-in-object-augmentation-and-namespacing http://michaux.ca/articles/javascript-the-good-parts-built-i...
- dstein 15y agoYou're okay as long as you don't extend Object which only leads to "hasOwnProperty" messiness. In cases where I might want to extend Object I use a static Object.foo(object) instead.
- kemayo 15y agoObject.prototype aside, I think it's a bad habit in any sort of large-ish system. Partially because of namespacing concerns; if prototype-extension happens in libraries you use, you might have common things like "startsWith" clobber each other with subtle incompatibilities. There's also visibility concerns. If you add random methods to things that look like language primitives it can be hard to get an overview of where they're really being used. Anecdotally, I had to go through and remove all use of prototype.js from deviantART because we decided to standardize on jQuery. It was a pain. A serious, serious pain. Because prototype.js extended Array, String, and other objects. So I had to go make a list of every single method that prototype.js added to these, and find all incidences of those somewhat-common strings in our codebase and examine them case-by-case to see if they were actually calling the prototype.js versions. By contrast, if I'd wanted to remove all use of jQuery I could have built an unambiguous list of all uses with a fairly simple grep.
- valyala 15y agoPerhaps, (this.lastIndexOf(s, 0) === 0) will work faster for startsWith(s), because it doesn't create new string just for the sole purpose of using it in a single comparison. What if s contains 1M 'a' chars, while this contains 1M 'b' chars? Your function will naturally make a copy of this, while it could only compare the first character in order to determine the result. The same applies to endWith() - { var pos = this.length - s.length; return (pos >= 0 && this.indexOf(s, pos) == pos); } will probably work faster in most cases.
- henning 15y agoThose functions are implemented inefficiently and they're ugly. How is this worthy of a blog post or a submission?
- birken 15y agoWhy do you think they are ugly?
- Jach 15y agoOne caveat: until the mythical PHP 6 comes out, if you're using unicode at all you should be using the multibyte string functions. http://www.php.net/manual/en/ref.mbstring.php http://www.php.net/manual/en/ref.mbstring.php Python has had unicode support for a while and generally does the right thing, something that might be missed with blind PHP replication.
- kleiba 15y agoI don't know PHP, but does the slice function work when $end > $start + $length?
- lox 15y agoWhat exactly does this do that isn't implemented with substr already? Have I misread the docs? Seems it handles positive and negative offsets. Also, wouldn't startsWith and endsWith also be already implemented as strpos and strrpos? Don't get me wrong, none of those functions are particularly elegant, but at least they are the "PHP way".
- wccrawford 15y agoI was just wishing I had 'startswith' the other day again in PHP. Not that I can't write it myself, but I just really hate to create global functions like that... Simple things like that should already exist.