2

In PHP, trim() exists.

By default the second parameter is " \n\r\t\v\x00"

I wish to introduce my own version which doesn't deviate far from the core functionality:

// Trim whitespace in addition to what the invoker requests
function trim_also( $string, $addl_characters = '' ){
    return trim( $string, $addl_characters." \n\r\t\v\x00" );
}

Having recently expanded our Composer ecosystem, I wish to do something like:

namespace local;

class Override {
    static function trim( $string, $addl_characters = '' ) {
        return trim( $string, $addl_characters." \n\r\t\v\x00" );
    }
    
    // Assume ltrim() and rtrim() will exist
    
    // Is it okay to have htmlentities() in here as well which sets defaults different than PHP?
}

This feels acceptable:

var_dump( \local\Override::trim( 'val1|val2|val3 | ', '|' ) );
// string(14) "val1|val2|val3"

What namespace/class naming and proximity scheme would you consider acceptable for such a function?

  • \local\Override::trim()
  • \local\Strings::trim()
  • \local\Helpers::trim()
  • \local\MonkeyZeus::trim()
  • \local\MonkeyZeus\Override::trim()
  • \local\Util\Override::trim()
  • \local\TrimStuff::trim() - considering my plans for htmlentities(), I don't like this one

I feel the function is not specific to me nor any business logic nor niche use-cases and the other developers would gladly use it.

5
  • It's been a while since I wrote php. Can't you add your own version of trim to a namespace, and call it via local\trim(...)? Do you really need a class? The namespace and Override class serve the same purpose in this case. Commented Oct 31 at 16:09
  • 1
    @GregBurghardt Due to Composer's PSR-4 autoloading, the class encapsulation avoids headaches. Yes, you could write something like <?php namespace local; function trim(){} ?> but then getting it to autoload involves additional hoops. Commented Oct 31 at 16:14
  • @GregBurghardt To note, I am okay with the class encapsulation. My main question revolves around namespace depth; would you consider this a root-ish function? Commented Oct 31 at 16:16
  • 1
    Usually questions asking for a name get closed as being opinion-based, but the constraints that Composer places on autoloading might make this question answerable. Can you include that information in your post? Knowing the constraints you must operate under is crucial. Commented Oct 31 at 18:08
  • 1
    Are you only writing these functions for one application, or do you plan on sharing them via a Composer package? Commented Oct 31 at 18:27

2 Answers 2

3

One may question the utility of such function in the first place, with several aspects to take into account:

  • Discoverability. That is, how I, working on your project, am expected to know that trim_also (or the modified trim) exists in the first place? How would I find it? Would my IDE, at some point, show it to me during autocompletion?

    Note that the answer to this question would guide you through the proper choice of the namespace.

  • Scope. Is this something very local, with a narrow scope, or the opposite, something shared between many different projects or transcending one huge project?

    Here too, the choice of the namespace would strongly depend on the answer.

  • Pertinence. Why would I need to use such function, as opposed to just having a string " \n\r\t\v\x00" stored somewhere in the code, that I can combine with my own set of characters to trim?

  • Use cases. How many times do I need to extend the base set of characters? How often those base set of characters actually matter? Don't know the specifics of your project, but virtually every time I had to use trim in any language, I was rather trimming something very specific—either some very domain-specific characters (say square brackets, for instance) or a series of carefully crafted characters, such as everything that is a whitespace. It was never the list you quoted—the zero byte at the end of especially... curious.

2
  • 1
    I would add "Are the any other, similar functions which might be grouped together with this one" to this list, though one can argue this is just another aspect of discoverability. Commented Nov 1 at 9:03
  • Thank you for this answer. I haven't finalized any decision but this will definitely help me to organize the codebase. FWIW: discoverability, good question! Yes, transcending one huge project; very enormous monolith. Pertinence, you have to remember a location regardless, the function takes on the concatenation responsibility. How many times? In our codebase, more than I'd like to admit... Commented 2 days ago
1

The premise of the question seems to be that trim() is the right name, now we just need to find a good class name because Composer wants a class when autoloading files. Instead, I would like to consider the semantics behind the additional characters (or why '' is a better default). What do these default characters mean from your application's perspective? Why isn't plain old trim() good enough?

Find that reason why, and use that to give your trim a better name. Once you have a better name for your "trim override", then let that guide your choice of name for the class that contains it.

Some other design and naming considerations:

  • If these functions are local utilities for a single application, consider omitting the namespace and just specify a class name or use some generic utils\ namespace.
  • If this is a general purpose utility which you alone are writing, and the potential audience is the general public (i.e., you are working on open-source), then use your own specific username as the root namespace. The goal here is to be unique within some package repository like Composer.
  • If this is a general purpose utility reusable by anyone at your organization, consider a namespace like myCompany\utils\. It should still be unique within your organization, even if you are using an internal package repository for Composer.
4
  • Thank you for this answer, it gives me food-for-thought. As for "Why isn't plain old trim() good enough?" there exists plenty of code like echo $city.', '.$state.' '.$zip;. When city or state+zip are empty then you get a visual anomaly. The new trim would trivialize this issue. The scope is local to my development team for our server; no one else. If I can generalize the functions enough then I may release it as a public package under the vendor/project hierarchy prescribed by Composer but that's not my current goal. Commented 2 days ago
  • @MonkeyZeus, can you edit your post to include that information? It's good to know the context of your problem. Commented 2 days ago
  • 1
    As some more food for thought, why not have a function that displays city, state, and zip with an empty() check before displaying the zip? You might be trying to solve the wrong problem. This logic could be put in a view model or domain model representing an address. Now you have a better context to decide on a name. Commented 2 days ago
  • Would it be wrong if I wish for that function to use the new trim() instead of dealing with a chain of empty checks? Regardless, that is one specific example. Another example would be cleaning up an implode which has empty leading or trailing values. Commented 17 hours ago

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.