You can put ',' instead of just ,.
Try this:
$arr = array('item1', 'item2', 'item3');
$str = "'" . implode("','", $arr) . "'";
echo $str;
Answer from Volkan Ulukut on Stack Overflowphp array implode explode with symbol - Stack Overflow
php - Using a callback in implode() - Stack Overflow
php - What is the difference between implode() & join() - Stack Overflow
String concatenation vs array implode in PHP - Stack Overflow
You can put ',' instead of just ,.
Try this:
$arr = array('item1', 'item2', 'item3');
$str = "'" . implode("','", $arr) . "'";
echo $str;
$array = array('item1', 'item2', 'item3');
$str = implode(',', array_map('add_quotes', $array));
function add_quotes($str) {
return sprintf("'%s'", $str);
}
echo $str;
Use array_map:
$final_string = implode(' | ', array_map(function($item) {
return '<a href="' . $item['uri'] . '">' . $item['title'] . '</a>';
}, $values));
I trust you'll properly escape the values as HTML in your real code.
As to why this works and your code doesn't, you were passing a function as the second argument to implode. Frankly, that makes little sense: you can join a bunch of strings together, or maybe even a bunch of functions, but you can't join a single function together. It sounds strange, especially if you word it that way.
Instead, we first want to transform all of the items in an array using a function and pass the result of that into implode. This operation is most commonly called map. Luckily, PHP provides this function as, well, array_map. After we've transformed the items in the array, we can join the results.
It seems that you need to assign the function to a variable, and then pass it through to make it work.
$fn = function($values) {
$return = array();
foreach($values as $value)
$return[] = '<a href="' . $value['uri'] . '">' . $value['title'] . '</a>';
return $return;
};
$final_string(' | ', $fn($values));
echo $final_string;
I am not sure what the reason is, though, and will need to check it in a little more depth to be able to give you a proper reason.
You can see the code working here
EDIT : Converted this answer to a community wiki so that everyone can contribute here.
EDIT : Explanation by @kmfk
When you pass the closure directly to the implode method - which explicitly wants a second argument of type array, it essentially checks the instanceof - hence the invalid argument. The implode function does not expect mixed type and doesn't know to execute the closure to get an array.
When you first assign that function to a variable, it causes PHP to first evaluate that variable and it ends up passing the returned value from the function into implode.
In that case you're returning an array from the function and passing that into implode - that checks out.
That anonymous function would be instanceof Closure, and
Closure !== array
They are aliases of each other. They should theoretically work exactly the same. Although, using explode/implode has been shown to increase the awesomeness of your code by 10%
Join: Join is an Alias of implode().
Example:
<?php
$arr = array('Test1', 'Test2', 'Test3');
$str = join(",", $arr);
echo $str;
?>
Output: Test1,Test2,Test3.
Implode: implode Returns a string from array elements.
Example:
<?php
$arr = array('Test1', 'Test2', 'Test3');
$str = implode(",", $arr);
echo $str;
?>
Output: Test1,Test2,Test3.
UPDATE:
I tested them in Benchmark and they are same in speed. There is no difference between them.
To me, using an array implies that you're going to do something that can't be done with simple string concatenation. Like sorting, checking for uniqueness, etc. If you're not doing anything like that, then string concatenation will be easier to read in a year or two by someone who doesn't know the code. They won't have to wonder whether the array is going to be manipulated before imploded.
That said, I take the imploded array approach when I need to build up a string with commas or " and " between words.
Choose the more readable one. Always. This case, i would pick up the second apporach. Then optimize it, if it's a bottleneck.
A long-liner that works with any number of items:
echo join(' and ', array_filter(array_merge(array(join(', ', array_slice($array, 0, -1))), array_slice($array, -1)), 'strlen'));
Or, if you really prefer the verboseness:
$last = array_slice($array, -1);
$first = join(', ', array_slice($array, 0, -1));
$both = array_filter(array_merge(array($first), $last), 'strlen');
echo join(' and ', $both);
The point is that this slicing, merging, filtering and joining handles all cases, including 0, 1 and 2 items, correctly without extra if..else statements. And it happens to be collapsible into a one-liner.
I'm not sure that a one liner is the most elegant solution to this problem.
I wrote this a while ago and drop it in as required:
/**
* Join a string with a natural language conjunction at the end.
* https://gist.github.com/angry-dan/e01b8712d6538510dd9c
*/
function natural_language_join(array $list, $conjunction = 'and') {
$last = array_pop($list);
if ($list) {
return implode(', ', $list) . ' ' . $conjunction . ' ' . $last;
}
return $last;
}
You don't have to use "and" as your join string, it's efficient and works with anything from 0 to an unlimited number of items:
// null
var_dump(natural_language_join(array()));
// string 'one'
var_dump(natural_language_join(array('one')));
// string 'one and two'
var_dump(natural_language_join(array('one', 'two')));
// string 'one, two and three'
var_dump(natural_language_join(array('one', 'two', 'three')));
// string 'one, two, three or four'
var_dump(natural_language_join(array('one', 'two', 'three', 'four'), 'or'));
It's easy to modify to include an Oxford comma if you want:
function natural_language_join( array $list, $conjunction = 'and' ) : string {
$oxford_separator = count( $list ) == 2 ? ' ' : ', ';
$last = array_pop( $list );
if ( $list ) {
return implode( ', ', $list ) . $oxford_separator . $conjunction . ' ' . $last;
}
return $last;
}