If I had:
$string = \"PascalCase\";
I need
\"pascal_case\"
Does PHP offer a function for this purpose?
Not fancy at all but simple and speedy as hell:
function uncamelize($str)
{
$str = lcfirst($str);
$lc = strtolower($str);
$result = '';
$length = strlen($str);
for ($i = 0; $i < $length; $i++) {
$result .= ($str[$i] == $lc[$i] ? '' : '_') . $lc[$i];
}
return $result;
}
echo uncamelize('HelloAWorld'); //hello_a_world
If you are not using Composer for PHP you are wasting your time.
composer require doctrine/inflector
use Doctrine\Inflector\InflectorFactory;
// Couple ways to get class name:
// If inside a parent class
$class_name = get_called_class();
// Or just inside the class
$class_name = get_class();
// Or straight get a class name
$class_name = MyCustomClass::class;
// Or, of course, a string
$class_name = 'App\Libs\MyCustomClass';
// Take the name down to the base name:
$class_name = end(explode('\\', $class_name)));
$inflector = InflectorFactory::create()->build();
$inflector->tableize($class_name); // my_custom_class
https://github.com/doctrine/inflector/blob/master/docs/en/index.rst
Most solutions here feel heavy handed. Here's what I use:
$underscored = strtolower(
preg_replace(
["/([A-Z]+)/", "/_([A-Z]+)([A-Z][a-z])/"],
["_$1", "_$1_$2"],
lcfirst($camelCase)
)
);
"CamelCASE" is converted to "camel_case"
lcfirst($camelCase)
will lower the first character (avoids 'CamelCASE' converted output to start with an underscore)[A-Z]
finds capital letters+
will treat every consecutive uppercase as a word (avoids 'CamelCASE' to be converted to camel_C_A_S_E)ThoseSPECCases
-> those_spec_cases
instead of those_speccases
strtolower([…])
turns the output to lowercasesdanielstjules/Stringy provieds a method to convert string from camelcase to snakecase.
s('TestUCase')->underscored(); // 'test_u_case'
function camel2snake($name) {
$str_arr = str_split($name);
foreach ($str_arr as $k => &$v) {
if (ord($v) >= 64 && ord($v) <= 90) { // A = 64; Z = 90
$v = strtolower($v);
$v = ($k != 0) ? '_'.$v : $v;
}
}
return implode('', $str_arr);
}
Ported from Ruby's String#camelize
and String#decamelize
.
function decamelize($word) {
return preg_replace(
'/(^|[a-z])([A-Z])/e',
'strtolower(strlen("\\1") ? "\\1_\\2" : "\\2")',
$word
);
}
function camelize($word) {
return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word);
}
One trick the above solutions may have missed is the 'e' modifier which causes preg_replace
to evaluate the replacement string as PHP code.