Collection::join

Joins collection values into a string, with a separate glue before the final element.

Signature
Collection::join(string $glue, string $finalGlue = ''): TValue|string

Parameters

ParameterTypeDescription
$gluestringThe separator placed between all elements except before the last one.
$finalGlueoptionalstring= ''The separator placed before the final element. Left at its default, the method behaves exactly like implode.

Return value

TValue|stringThe joined string, using finalGlue before the last element. An empty collection returns an empty string; a single-item collection returns that item itself, unconverted.

join is implode with one extra idea: a different separator before the last element. That single addition turns a list into a sentence — "Ada, Grace and Linus" — without the array_pop and string concatenation the job usually takes.

When to reach for it

Any user-facing list: notification bodies, validation messages naming several fields, a summary of selected filters. It handles the awkward cases for free — two items get only the final glue with no leading comma, one item is returned alone, and an empty collection produces an empty string rather than a stray separator.

Watch the spacing in your glue

Both separators are used verbatim, so the spaces are yours to supply. join(', ', ' and ') gives "a, b and c"; join(', ', ', and ') gives the Oxford-comma form "a, b, and c". Forgetting the leading space in the final glue is the usual cause of "a, band c".

The thing that trips people up

With finalGlue left empty the method delegates straight to implode, which means it inherits implode's scalar-versus-record argument handling. And a single-item collection returns that item as it is — collect([5])->join(', ', ' and ') returns the integer 5, not the string '5', so code that type-hints a string return will fail on exactly the one-element case.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Render a natural-language list of selected filters in a notification or heading.
  • Name several invalid fields in a single validation message.
  • Produce an Oxford-comma list for copy that has to match a style guide.

Frequently asked questions

What is the difference between join and implode?

join takes a second glue used only before the final element, which produces natural-language lists like "a, b and c". implode uses one separator throughout and additionally supports plucking a key from records.

What does join return for an empty or single-item collection?

An empty collection returns an empty string. A single-item collection returns that item as it is, not converted to a string — so collect([5])->join(', ', ' and ') returns the integer 5.

How do I get an Oxford comma?

Put the comma in the final glue: join(', ', ', and ') produces "a, b, and c", while join(', ', ' and ') produces "a, b and c". Both separators are inserted verbatim, so include the spaces yourself.

More examples

Shaping values before joining

The outputs are "Ada, Grace and Linus" and "1.50 and 2.25". Unlike implode, join has no key-plucking form — its first argument is always the glue — so a collection of records needs an explicit pluck or map first. That is a feature: there is no argument-shape ambiguity to fall into.

Example · php
<?php
$users = collect([
    ['name' => 'Ada'],
    ['name' => 'Grace'],
    ['name' => 'Linus'],
]);

// join reads values, so pluck the column first.
echo $users->pluck('name')->join(', ', ' and '), PHP_EOL;

// Format each value, then join.
echo collect([1.5, 2.25])->map(fn ($n) => number_format($n, 2))->join(', ', ' and '), PHP_EOL;

Every list length, and the string-return trap

The loop prints an empty string, then a, then "a and b", then "a, b and c" — no leading or trailing separators at any length. The var_dumps show int(5) and then string(1) "5": the single-item shortcut returns the raw item, so cast the result when the caller declares a string return type.

Example · php
<?php
foreach ([[], ['a'], ['a', 'b'], ['a', 'b', 'c']] as $items) {
    printf("%d: %s\n", count($items), collect($items)->join(', ', ' and '));
}

// One item is returned unconverted, so guard a string contract:
$one = collect([5])->join(', ', ' and ');
var_dump($one);
var_dump((string) collect([5])->join(', ', ' and '));

A validation message in application code

The first line prints "Please provide your email, phone and address." and the second "Please provide your email, phone, and address." The only difference is the comma inside the final glue, which is where the whole style decision lives — both separators are inserted verbatim, spaces included.

Example · php
<?php
$missing = collect(['email', 'phone', 'address']);

$message = 'Please provide your '.$missing->join(', ', ' and ').'.';

echo $message, PHP_EOL;

// Oxford comma variant for a stricter style guide.
echo 'Please provide your '.$missing->join(', ', ', and ').'.', PHP_EOL;

Discussion

  • Be the first to comment on this lesson.