In PHP, how do explode(), implode() and trim() behave when you split a comma-separated list of invoice codes, and which edge cases bite?
answer
- separator is the first argument
- limit keeps the rest in the last element
- empty input gives one empty element
- empty separator throws ValueError
- trim takes a character list
basics
~20 sexplode(',', $s) splits on a separator and returns an array, implode(',', $parts) joins it back, and trim() strips whitespace. Traps: an empty string explodes to [''], an empty separator throws ValueError, and trim's second argument is a set of characters.
solid answer
~40 s`explode(string $separator, string $string, int $limit = PHP_INT_MAX): array` splits on every occurrence of the separator. A positive `$limit` caps the number of elements and leaves the remainder in the last one; a negative limit drops that many elements from the end. Exploding an empty string returns `['']`, one empty element, so `count()` is 1, and since PHP 8.0 an empty separator throws `ValueError`. `implode(', ', $parts)` joins with the separator first; the old reversed argument order was removed in 8.0. `trim()` strips spaces, tabs, newlines, carriage returns, vertical tabs and NUL bytes from both ends, and its optional second argument is a **list of characters**, not a substring, so `rtrim('1200', '0')` returns `'12'`. A robust split maps `trim` over the parts and drops the empty ones.
code
php · 15 lines<?php
declare(strict_types=1);
$raw = " INV-001, INV-002 ,,INV-003\n";
$codes = array_map(trim(...), explode(',', $raw));
$codes = array_values(array_filter($codes, fn (string $c): bool => $c !== ''));
echo implode(';', $codes), "\n"; // INV-001;INV-002;INV-003
var_dump(explode(',', '')); // array(1) { [0]=> string(0) "" }
var_dump(explode(',', 'a,b,c', 2)); // ['a', 'b,c']
var_dump(explode(',', 'a,b,c', -1)); // ['a', 'b']
var_dump(trim('INV-001-INV', 'INV')); // string(5) "-001-"
var_dump(rtrim('1200', '0')); // string(2) "12"go deeper
Recall the argument order of explode and implode, the default characters trim removes, and that trimming each part is part of a clean split.
Explain the positive, negative and zero limit rules, the [''] result for an empty string, the ValueError for an empty separator and trim's character-set argument.
Show you would harden an import against empty parts, pasted Unicode whitespace and '0' values that a callback-less array_filter drops, and switch to a CSV parser when fields can contain the separator.
Argue when ad hoc explode parsing is acceptable versus when a documented format and a real parser should be mandated for data exchanged with other systems.
## Splitting with explode() `explode(string $separator, string $string, int $limit = PHP_INT_MAX): array` cuts `$string` at every occurrence of `$separator` and returns the pieces as a list. The separator comes **first** and the string second; swapping them is a common slip. The `$limit` argument changes the shape of the result: | Call | Result | Rule | |---|---|---| | `explode(',', 'a,b,c,d')` | `['a', 'b', 'c', 'd']` | split everywhere | | `explode(',', 'a,b,c,d', 2)` | `['a', 'b,c,d']` | at most 2 elements; the last holds the rest | | `explode(',', 'a,b,c,d', -1)` | `['a', 'b', 'c']` | drop the last element | | `explode(',', 'a,b,c,d', 0)` | `['a,b,c,d']` | 0 is treated as 1 | | `explode(',', 'abcd')` | `['abcd']` | no separator: one element | | `explode(',', '')` | `['']` | empty input: one empty element | A positive limit is useful for `key=value` lines where the value may itself contain the separator: `explode('=', $line, 2)` always yields at most two parts. ## Edge cases that bite 1. **Empty input is not an empty array.** `explode(',', '')` returns an array with one empty string, so `count()` is `1`. Code that asks "were any invoice codes supplied?" with `count(explode(...)) > 0` always says yes. 2. **Empty separator.** Since PHP 8.0 `explode('', $s)` throws a `ValueError`; before, it returned `false` with a warning. Splitting into single bytes is `str_split()`'s job. 3. **Adjacent separators.** `'a,,b'` produces an empty element in the middle, and a trailing comma produces one at the end. 4. **Whitespace survives.** `' INV-001, INV-002 '` explodes into elements that still carry their spaces. ## Cleaning the parts with trim() `trim(string $string, string $characters = " \n\r\t\v\0"): string` removes characters from both ends. The default set is: - the space `" "` - newline `\n` and carriage return `\r` - horizontal tab `\t` and vertical tab `\v` - the NUL byte `\0` `ltrim()` works only on the left, `rtrim()` only on the right, and `chop()` is an alias of `rtrim()`. The second argument is a **set of characters**, not a substring to remove. Any character in the set is stripped, in any order, until a character outside the set is reached: - `trim('INV-001-INV', 'INV')` returns `'-001-'`, because `I`, `N` and `V` are each stripped from both ends. - `rtrim('1200', '0')` returns `'12'`, which silently corrupts an amount if you meant to drop only formatting zeros. - A range can be written with `..`, as in `trim($binary, "\x00..\x1F")` to strip control bytes. `trim()` works on bytes and knows nothing about Unicode, so a UTF-8 non-breaking space pasted from a spreadsheet is **not** removed by default; the multibyte counterparts handle that. A robust split of a user-typed list therefore combines three steps: 1. `explode(',', $raw)` to cut the string; 2. `array_map(trim(...), ...)` to clean each part; 3. drop the empty strings with a callback that tests `$c !== ''`. Calling `array_filter()` **without** a callback is a trap here: it removes every falsy value, and the string `'0'` is falsy. ## Joining with implode() `implode(string $separator, array $array): string` glues the elements with the separator between them. `join()` is an alias. Details: - `implode(', ', [])` returns `''`. - `implode($array)` with a single argument uses an empty separator. - The legacy reversed order `implode($pieces, $glue)` was deprecated in PHP 7.4 and **removed in 8.0**. - Elements are converted to strings, so `implode(',', [1, 2.5, true])` gives `'1,2.5,1'`. `explode()` and `implode()` are not a quoting format: a code that itself contains the separator cannot round-trip. When fields may contain commas or quotes, use a real CSV parser instead. ## What a strong answer covers Name the argument order, the `$limit` semantics, the `['']` result for an empty string and the `ValueError` for an empty separator. Then show that you clean the pieces with `trim()`, know its default character list, and know that its second argument is a character set. That combination is what separates someone who has debugged an import from someone who has only read the signature.
- Why does count(explode(',', $input)) > 0 fail as a check that at least one invoice code was supplied?Because, without a negative limit, `explode()` does not return an empty array: an empty `$input` yields `['']`, so the count is 1. Check the trimmed input for `''` first, or filter out empty strings after splitting and count what remains.
- What does the second argument of trim() mean, and why does rtrim('1200', '0') return '12'?It is a list of characters to strip, not a substring. `rtrim()` removes any listed character from the right end until it meets one that is not listed, so both zeros go. To drop an exact suffix, test with `str_ends_with()` and cut with `substr()` instead.
- What happens in PHP 8 when explode() receives an empty separator?It throws a `ValueError`. Before PHP 8.0 it emitted a warning and returned `false`. If the goal is to split a string into single bytes, `str_split()` is the function for that; for characters in UTF-8 text use the multibyte variant.
saying these in an interview costs you the question
- explode returns an empty array when the input string is empty.
- trim's second argument removes that exact substring from the ends.
- trim also strips non-breaking spaces and other Unicode whitespace by default.
- implode accepts the array and the separator in either order in PHP 8.
- explode with an empty separator splits the string into characters.
- A limit of 2 throws away everything after the second element.