Skip to content

Instantly share code, notes, and snippets.

@jesseschalken
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jesseschalken/80c8659916da1e550677 to your computer and use it in GitHub Desktop.
Save jesseschalken/80c8659916da1e550677 to your computer and use it in GitHub Desktop.
Join a list of arbitrary strings together so they can be split apart again, ie split(join($x)) === $x for all $x
<?php
namespace JoinSplit;
/**
* @param string[] $a
* @return string
*/
function join(array $a) {
$r = '';
foreach ($a as $x) {
$x = str_replace('\\', '\\\\', $x);
$x = str_replace(';', '\\;', $x);
$r .= $x . ';';
}
return $r;
}
/**
* @param string $s
* @return string[]
*/
function split($s) {
$r = array();
$b = '';
$l = strlen($s);
$e = false;
for ($i = 0; $i < $l; $i++) {
$c = $s[$i];
if ($e) {
$b .= $c;
$e = false;
} else if ($c === '\\') {
$e = true;
} else if ($c === ';') {
$r[] = $b;
$b = '';
} else {
$b .= $c;
}
}
return $r;
}
/**
* @throws \Exception
*/
function test() {
static $tests = array(
array(),
array(''),
array('"'),
array('""'),
array(','),
array(';'),
array('\\'),
array('\\"'),
array("\n"),
array("\r"),
array("\v"),
array("\t"),
array(" "),
array("\r\n"),
array('"', '""', ';', '', ',', "\n"),
array("\x00", 'lololol'),
array("\x00", '0'),
array("\x00"),
);
foreach ($tests as $test1) {
$test2 = split(join($test1));
if ($test1 !== $test2) {
$test1 = var_export($test1, true);
$test2 = var_export($test2, true);
throw new \Exception("expected $test1, got $test2");
}
}
}
test();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment