• Björn Tantau (unregistered)

    I hate finding such code. And I even hate it more when I find it in some widely used library, which happens too often with PHP.

    No, I can't name any names. I'm too lazy to look.

    And I guess I was too lazy to make merge requests.

  • Jonas (unregistered)

    What strange json standard allows for a trailing comma?

  • (nodebb)

    At least 10% WTFPV (WTF by volume) goes to PHP for choosing shite function names. Well yes, it's in the manual, in a section something to do with stringly things, but looking for, say, 'concat' won't find it. I don't know if implode is common usage, but as ESL if I didn't know and had to guess, 'implode' is something I'd rather wish PHP itself to do.

  • DFYX (unregistered) in reply to Applied Mediocrity

    To be fair, PHP also defines 'join' (since PHP4) as an alias for 'implode' which matches what Java, C#, Ruby, Python and probably other languages use. On the other hand, needing aliases for common standard library function without deprecating the old names feels... weird.

  • Michal Molhanec (google)

    No, in standard JSON (https://www.json.org/) you cannot have trailing commas and I think the reason was incorrect handling in some old IEs. Of course, there is JSON 5 (https://json5.org/), but not really in general use.

  • Bradley (unregistered)

    Trailing commas in JSON are definitely NOT valid according to the official spec.

  • WTFGuy (unregistered)

    Back in the day before iterators, OMs, and Join by any other name, I always used the idiom with the extra comma on the front.

    // assuming zero-origin indexing; never a sure thing in the Olden Tymes
    string buffer = "" ;
    for (idx=0, length(someArray), idx++) {
        buffer = buffer & "," & someArray[idx];
    buffer = substring(buffer,1)   // trim off excess comma

    It always seemed like it was clearer and it wasn't fussy figuring out where the end was to trim off the excess comma. In pointer-oriented languages it was an especially cheap to trim the buffer just by advancing the start pointer by 1 characters' worth. Only later did languages begin supporting the substring idiom that negative offsets counted from end.

  • (nodebb)

    Remy and TheDailyWTF readers

    Is that the name of your new band?

  • (nodebb) in reply to Michal Molhanec

    Of course, there is JSON 5 (https://json5.org/), but not really in general use.

    Having read the link, I can see it needs to die a death and never be mentioned again.

  • Naomi (unregistered) in reply to Jeremy Pereira


  • Tom (unregistered)

    Not much of a WTF. Yes, it's inelegant, but it's arguably faster than checking if you're on the last iteration (better branch prediction).

  • (nodebb) in reply to Naomi

    Because JSON is a data interchange format. It's designed to be lightweight and unambiguous and the original version did the job admirably. Most of the listed "improvements" are there to make it easier for humans to read (and write by hand) JSON at the expense of making parsers more complex. For example: comments are not necessary for data interchange and were explicitly excluded from the original spec because the designers found that there was a tendency to shoehorn semantics into them.

    You could argue that the changes make JSON5 a better format for configuration files, but it's still going to be pretty crap for that.

  • Brian (unregistered) in reply to Applied Mediocrity

    I'd assume "implode" came about because "explode" is the function that breaks a string into an array (also a dumb name, but at least makes some kind of sense), and someone thought it would be cute to use the inverse name for the inverse operation.

    More sensible languages use more boring but obvious names like split and join.

  • Anonymous') OR 1=1; DROP TABLE wtf; -- (unregistered) in reply to Applied Mediocrity

    Fun fact: many of the early PHP functions have such weird names because, I kid you not, the hash function used by the parser was strlen().


  • Code Refactorer (unregistered)

    The real WTF is that first, the code throws an index-out-of-bounds error in the substring command if the previous loop executed zero times. And second, that you waste a lot of memory and time when the resulting string becomes very big, let's assume 100000 bytes, you are copying 99999 bytes over just to remove the delimiter from the beginning or end. I have seen this type of code already many times and in nearly one third of the cases it was crashing or returning a wrong result. Especially by programmers that like to use a do-it-wrong-and-correct-afterwards-algorithm instead of a do-it-right-the-first-time algorithm.

    Is it really so hard to do it right?:

    $query = ''; $delimiter=''; foreach ($postdata as $var => $val) { $query .= $delimiter.$var .'='. $val; $delimiter='&'; }

  • Raj (unregistered) in reply to DFYX

    The join in Python is TRWTF because it's a method of the separator (string) that takes the list as a parameter.

  • substr('Comment!', 0, -1) (unregistered)

    This is a pretty weak WTF, it's functional (apart from the empty list edge case, but it's probably never called with an empty) code that replicates a built in function that the developer probably couldn't find because, well, PHP. There's nothing wrong with using a negative index to substr, that's fully documented behaviour and this is an intelligent use of it.

    Sure, he should have used implode, but not knowing about a library function is hardly a WTF. I've accidentally reimplemented framework functions I didn't know about before too.

    Edit: TRWTF is the captcha which decided I needed to verify like 10 of its stupid puzzles

  • Joseph D (unregistered)

    I feel like the real WTF is that the "var"s and "val"s aren't being percent-encoded. So if a val has an ampersand sign, it wouldn't get escaped. Or am I missing something? (I'm not very familiar w/ PHP.)

  • Peter of the Norse (unregistered)

    I’m wondering if this shouldn’t be replaced with http_build_query which does the exact same thing, but also escapes the values too.

    If that’s not the case, this might be the best way to do it. The only other way would be to make a new array that contains all of the new values and implode that. And if the size of the array is large, that can take a lot of memory.

    I know that one of the improvements that came with PHP 7 is in-place string manipulation. So that code like $s = strtolower($s) no longer makes a copy. I don’t know if that has extended to substr, but this might be the faster, cheaper way to do it.

  • Peter of the Norse (unregistered)

    Also, calling substr on an empty string is not a warning.

  • (nodebb)

    I've dealt with this mess at least in some personal quick-hack code, writing loops that stop at " num_elements - 1" and following with some non-comma-containing final concatenation.

    Thanks to this dailyWTF , I've become inspired to write a concatenation loop that gives me the string "frist,second,third,foarth," and follow that with

     regexpr(string,  '[,]$', '') 

  • sizer99 (google)

    This is one of those nice cases where the sane approach of Join( ", ", items) is 1) easier to read, 2) faster, 3) less prone to errors. Not often you get a win win win situation. Except now when I run into code that doesn't use join (because the language doesn't have it or the person using it didn't know about it) it hurts all the more.

  • PotatoEngineer (unregistered)

    I can understand JSON-purity from a data-exchange point of view, but I use JSON intermittently in config files, where comments and slightly-looser rules would make it much easier to write. If I change values in a config file, it's really helpful to leave a comment on why it's changed, or else I'm just going to change it back once I've forgotten the reason. And while you can add extra properties to be some sort of comment {"val":"thing","comment":"this is why val is thing"}, it's a much uglier hack than just allowing comments.

  • Future (unregistered)


    (Apple has an equivalent ListFormatter)

  • Staticsan (unregistered)

    Two things.

    • I've removed so much PHP code that does that stupid remove-the-last-comma thing and changed it to use an imploded list. What's even more annoying is that in older versions of PHP, copying strings around was an expensive operation so you wanted to avoid unnecessary string copying. Which is what looped concatenation was doing. So the imploded list was not only more elegant it was substantially faster?

    • I'd happily forgotten Crockford invented JSON. I had a look at JSON5 and quite a number of its proposals I think should've been in the original spec, particularly comments (although I reluctantly understand why he chose to take them out) and trailing commas. Except they weren't because Crockford.

  • (nodebb)

    When I am writing in VBA6 (still in use as the default macro language for MS-Office), I do something similar and stick it in a Module:

    Public Function JoinArray(Text() as String, Optional Delimiter As String = ",") as String
       Dim I as Integer, Result as String   ' Sorry, no string builder
       For I=LBound(Text) to UBound(Text)
          Result = Result & Delimiter & " " & Text(I)
       Next I
       If Left$(Result, 1) = Delimiter Then   ' Make sure the string starts with a comma anyway.
          Result = Trim$(Mid$(Result, 2))  ' Throw away the leading comma and any leading spaces.  Assume one-character delimiter.
       End If
       JoinArray = Result
    End Function
  • (nodebb)

    People generate JSON by hand???? Why?

  • I dunno LOL ¯\(°_o)/¯ (unregistered) in reply to substr('Comment!', 0, -1)

    TRWTF is the captcha which decided I needed to verify like 10 of its stupid puzzles

    Captcha these days seems to have some timing-dependent factor to it. The result is that if it doesn't like your browser, answering too fast, especially if there are timing glitches in your browser that delay and cluster your clicks, will cause it to decide that you are a bot. Because of course bots are able to identify and click that shit in 500ms. Then it starts hitting you with 5-up sets and slow-fades which only cause you to try to answer faster, and you start making mistakes too. There's a limit of 3 sets that it will give you, but I've had even that sometimes not be accepted on a certain web site. And then it starts giving you rate limiting errors, after making you answer more and more.

    Since I started answering it slowly, I've had much better results in my preferred non-mainstream browser. "Walk without rhythm and you won't attract the worm." But there is a serious WTF at work here, the captcha team has clearly lost touch with their original goal of detecting humans. Now a really good human is detected as a bot unless he slows himself down. If they think you're a bot because you can answer in less than one second, they should be knocking on your door to license your technology.

    And then there's the "crosswalk" that is a rumble strip in a highway median, and the "parking meter" that is a mailbox. I'm going to guess that they don't dogfood themselves with their own captchas.

  • pavlov (unregistered) in reply to Raj

    The possible reason for this is that python 'join' works with anything that is iterable, not only with lists. And I think there is no python way to introduce a Joinable or whatever baseclass to provide 'join' as a function, because anything that is iterable means not only common containers or other classes but literally anything that is iterable, generator expressions for example.

  • jgh (unregistered)

    Well, to be fair, it's PHP. There is no manual. The only way to find what commands and functions exist is hours of searching the web. And there's no logic, so if you find one you can't apply common sense and extrapolate to another. strlen give me the length of a string. Ah! String functions start with str. Nope. str_repeat. Ok, str or str_. Nope! substr. Grrrr. substr_count. What? strrchr finds a character searching from the right, so clearly strlchr searches from the left. No? What? strchr??? WTF?

  • David Mårtensson (unregistered) in reply to Michal Molhanec

    Since Json was born out of javascripts handling, a trailing comma would create an array one bigger than intended with the last item being undefined.

    And that would break the format.

  • giocarmine (unregistered) in reply to Applied Mediocrity

    Well, i don't know so much about PHP but when i have to do something like that in a language that i don't know i usually google something like "string join in <language>" and 99.9% of the times i find different solutions on StackOverflow, usually with nice arguments on which one is the best practice and why..

Leave a comment on “The Concatenator”

Log In or post as a guest

Replying to comment #:

« Return to Article