1. 需求:和客户端传输数据的字段名需要使用小驼峰命名。客户端使用小驼峰,服务端PHP使用下划线命名。示例:图片链接  imgUrl。客户端传过来的小驼峰字段转换成下划线格式  img_url。
  2. PHP实现:
    /**
         * 下划线转小驼峰, 数组是对键名进行转换,数组值不变
         * 转换结果举例
         * little_boy => littleBoy
         * _title => title
         * title_ => title
         * _title_ => title
         * little__boy => littleBoy
         * title_boy__girl_中文_title => titleBoyGirl中文Title
         * @param string|array $data
         * @return mixed
         * @throws
         */
        function underline2Camel($data)
        {
            if (is_string($data)) {
                $_data = explode('_', $data);
                $count = count($_data);
                if ($count == 1) {
                    // 没有“_”情况, 原样返回
                    return $data;
                }
                // 下划线分隔的单词,除第一个外,其余首字母转大写就实现了下划线转驼峰需求。特殊字符不变。
                $new_str = $_data[0];
                $start = 1;
                // 处理第一个字符是 “_” 的情况, 不能转换成大驼峰。示例:_title 要转成 title 而不是 Title
                if ($data[0] == '_') {
                    $new_str .= $_data[1];
                    $start = 2;
                }
                for ($i = $start; $i < $count; $i++) {
                    $_data[$i] = ucfirst($_data[$i]);
                    $new_str .= $_data[$i];
                }
                return $new_str;
            } elseif (is_array($data)) {
                foreach ($data as $k => $v) {
                    if (is_array($v)) {
                        // 如果是多维数组,递归转换
                        $_k = self::underline2Camel($k);
                        $data[$_k] = self::underline2Camel($v);
                        unset($data[$k]);
                    } else {
                        // 数组下标如果是数字,则不处理
                        if (is_numeric($k)) {
                            continue;
                        }
                        $_k = self::underline2Camel($k);
                        $data[$_k] = $data[$k];
                        unset($data[$k]);
                    }
                }
                return $data;
            } else {
                throw new \Exception('不支持的数据类型:' . gettype($data));
            }
        }
    下划线转小驼峰
    /**
         * 驼峰转下划线, 数组是对键名进行转换,值不变
         * littleBoy => little_boy
         * @param string|array $data
         * @return mixed
         * @throws
         */
        function camel2Underline($data)
        {
            if (is_string($data)) {
                $data = trim($data);
                $len = strlen($data);
                // 首字母是大写的情况,首字母直接转小写不加下划线
                $new_str = (ord($data[0]) >= 65 && ord($data[0]) <= 90) ? chr(ord($data[0]) + 32) : $data[0];
                for ($i = 1; $i < $len; $i++) {
                    $ascii = ord($data[$i]);
                    if ($ascii >= 65 && $ascii <= 90) {
                        $new_str .= '_' . chr($ascii + 32);
                    } else {
                        $new_str .= $data[$i];
                    }
                }
                return $new_str;
            } elseif (is_array($data)) {
                foreach ($data as $k => $v) {
                    // 处理多维数组的情况
                    if (is_array($v)) {
                        $_k = self::camel2Underline($k);
                        $data[$_k] = self::camel2Underline($v);
                        unset($data[$k]);
                    } else {
                        // 数组下标如果是数字,则不处理
                        if (is_numeric($k)) {
                            continue;
                        }
                        $_k = self::camel2Underline($k);
                        $data[$_k] = $data[$k];
                        unset($data[$k]);
                    }
                }
                return $data;
            } else {
                throw new \Exception('不支持的数据类型:' . gettype($data));
            }
        }
    驼峰转下划线

     

  3. 更新:上面的版本不支持下标为数字的多维数组,比如下面的数组下标2对应的数组
    $data = ['img_url' => 'dssd', 'user_name' => 'dfd', 1 => 'asd', 2 => ['u_a' => 'xcz'], 'user_bb' => ['aa_cc' => 'xxx', 'cc_dd' => ['ee_ff' => 'fds']]];

    也不支持数组下标为全小写的数组,比如下面数组下标username对应的数组

    $data = ['img_url' => 'dssd', 'username' => 'dfd', 1 => 'asd', 2 => ['u_a' => 'xcz'], 'user_bb' => ['aa_cc' => 'xxx', 'cc_dd' => ['ee_ff' => 'fds']]];

    之前版本中上面的两种情况会被过滤掉,新版兼容了这两种情况。并增加了一些测试的例子。新版使用类的形式。

    class Util
    {
        /**
         * 下划线转小驼峰, 数组是对键名进行转换,数组值不变
         * 转换结果举例
         * little_boy => littleBoy
         * _title => title
         * title_ => title
         * _title_ => title
         * little__boy => littleBoy
         * title_boy__girl_中文_title => titleBoyGirl中文Title
         * @param string|array $data
         * @return mixed
         * @throws
         */
        public static function underline2Camel($data)
        {
            if (is_string($data)) {
                $_data = explode('_', $data);
                $count = count($_data);
                if ($count == 1) {
                    // 没有“_”情况, 原样返回
                    return $data;
                }
                // 下划线分隔的单词,除第一个外,其余首字母转大写就实现了下划线转驼峰需求。特殊字符不变。
                $new_str = $_data[0];
                $start = 1;
                // 处理第一个字符是 “_” 的情况, 不能转换成大驼峰。示例:_title 要转成 title 而不是 Title
                if ($data[0] == '_') {
                    $new_str .= $_data[1];
                    $start = 2;
                }
                for ($i = $start; $i < $count; $i++) {
                    $_data[$i] = ucfirst($_data[$i]);
                    $new_str .= $_data[$i];
                }
                return $new_str;
            } elseif (is_array($data)) {
                foreach ($data as $k => $v) {
                    if (is_array($v)) {
                        // 如果是多维数组,递归转换.(如果下标是数字的值又是一个数组,那么仍需要递归转换,数字保留不变)
                        $_k = is_numeric($k) ? $k : self::underline2Camel($k);
                        $data[$_k] = self::underline2Camel($v);
                        if (!is_numeric($k)) unset($data[$k]); // 数组下标为数字的不能删除,因为$k == $_k
                    } else {
                        // 数组下标如果是数字,则不处理
                        if (is_numeric($k)) {
                            continue;
                        }
                        $_k = self::underline2Camel($k);
                        $data[$_k] = $data[$k];
                        if ($k !== $_k) unset($data[$k]);
                    }
                }
                return $data;
            } else {
                throw new \Exception('不支持的数据类型:' . gettype($data));
            }
        }
    
        /**
         * 驼峰转下划线, 数组是对键名进行转换,值不变
         * littleBoy => little_boy
         * @param string|array $data
         * @return mixed
         * @throws
         */
        public static function camel2Underline($data)
        {
            if (is_string($data)) {
                $data = trim($data);
                $len = strlen($data);
                // 首字母是大写的情况,首字母直接转小写不加下划线
                $new_str = (ord($data[0]) >= 65 && ord($data[0]) <= 90) ? chr(ord($data[0]) + 32) : $data[0];
                for ($i = 1; $i < $len; $i++) {
                    $ascii = ord($data[$i]);
                    if ($ascii >= 65 && $ascii <= 90) {
                        $new_str .= '_' . chr($ascii + 32);
                    } else {
                        $new_str .= $data[$i];
                    }
                }
                return $new_str;
            } elseif (is_array($data)) {
                foreach ($data as $k => $v) {
                    // 处理多维数组的情况
                    if (is_array($v)) {
                        // 如果是多维数组,递归转换.(如果下标是数字的值又是一个数组,那么仍需要递归转换,数字保留不变)
                        $_k = is_numeric($k) ? $k : self::camel2Underline($k);
                        $data[$_k] = self::camel2Underline($v);
                        if (!is_numeric($k)) unset($data[$k]); // 数组下标为数字的不能删除,因为$k == $_k
                    } else {
                        // 数组下标如果是数字,则不处理
                        if (is_numeric($k)) {
                            continue;
                        }
                        $_k = self::camel2Underline($k);
                        $data[$_k] = $data[$k];
                        if ($k !== $_k) unset($data[$k]); // 数组下标如果是全小写,例如:uid,是不能删除的。要保留
                    }
                }
                return $data;
            } else {
                throw new \Exception('不支持的数据类型:' . gettype($data));
            }
        }
    
        // 测试
        public static function testUnderline2Camel()
        {
            $str1 = '_title';
            $str2 = 'title_';
            $str3 = '_title_';
            $str4 = 'title_boy__girl_中文_title';
            $data = ['img_url' => 'dssd', 'user_name' => 'dfd', 1 => 'asd', 2 => ['u_a' => 'xcz'], 'user_bb' => ['aa_cc' => 'xxx', 'cc_dd' => ['ee_ff' => 'fds']]];
            $data = ['img_url' => 'dssd', 'username' => 'dfd', 1 => 'asd', 2 => ['u_a' => 'xcz'], 'user_bb' => ['aa_cc' => 'xxx', 'cc_dd' => ['ee_ff' => 'fds']]];
            dump(Util::underline2Camel($str1));
            dump(Util::underline2Camel($str2));
            dump(Util::underline2Camel($str3));
            dump(Util::underline2Camel($str4));
            dump(Util::underline2Camel($data));
            dump(Util::camel2Underline(Util::underline2Camel($data)));
            dump(Util::camel2Underline(Util::underline2Camel($str4)));
            dump(Util::camel2Underline(Util::underline2Camel($str3)));
    
            die();
        }
    }
    更新版

     

  4. 2022/8/18更新:发现了一个小bug:当传入的参数是数组并且索引是驼峰的情况下,驼峰索引对应的元素值会被删掉。已修复
    class Util
    {
        /**
         * 下划线转小驼峰, 数组是对键名进行转换,数组值不变
         * 转换结果举例
         * little_boy => littleBoy
         * _title => title
         * title_ => title
         * _title_ => title
         * little__boy => littleBoy
         * title_boy__girl_中文_title => titleBoyGirl中文Title
         * @param string|array $data
         * @return mixed
         * @throws
         */
        public static function underline2Camel($data)
        {
            if (is_string($data)) {
                $_data = explode('_', $data);
                $count = count($_data);
                if ($count == 1) {
                    // 没有“_”情况, 原样返回
                    return $data;
                }
                // 下划线分隔的单词,除第一个外,其余首字母转大写就实现了下划线转驼峰需求。特殊字符不变。
                $new_str = $_data[0];
                $start = 1;
                // 处理第一个字符是 “_” 的情况, 不能转换成大驼峰。示例:_title 要转成 title 而不是 Title
                if ($data[0] == '_') {
                    $new_str .= $_data[1];
                    $start = 2;
                }
                for ($i = $start; $i < $count; $i++) {
                    $_data[$i] = ucfirst($_data[$i]);
                    $new_str .= $_data[$i];
                }
                return $new_str;
            } elseif (is_array($data)) {
                foreach ($data as $k => $v) {
                    if (is_array($v)) {
                        // 如果是多维数组,递归转换.(如果下标是数字的值又是一个数组,那么仍需要递归转换,数字保留不变)
                        $_k = is_numeric($k) ? $k : self::underline2Camel($k);
                        $data[$_k] = self::underline2Camel($v);
                        if ($k !== $_k) unset($data[$k]);
                    } else {
                        // 数组下标如果是数字,则不处理
                        if (is_numeric($k)) {
                            continue;
                        }
                        $_k = self::underline2Camel($k);
                        $data[$_k] = $data[$k];
                        if ($k !== $_k) unset($data[$k]);
                    }
                }
                return $data;
            } else {
                // throw new \Exception('不支持的数据类型:' . gettype($data));
                // 考虑到数组中某个元素值可能会包含对象,这种情况不能抛出异常不合理。改成原样返回数据,不做处理。
                return $data;
            }
        }
    
        /**
         * 驼峰转下划线, 数组是对键名进行转换,值不变
         * littleBoy => little_boy
         * @param string|array $data
         * @return mixed
         * @throws
         */
        public static function camel2Underline($data)
        {
            if (is_string($data)) {
                $data = trim($data);
                $len = strlen($data);
                // 首字母是大写的情况,首字母直接转小写不加下划线
                $new_str = (ord($data[0]) >= 65 && ord($data[0]) <= 90) ? chr(ord($data[0]) + 32) : $data[0];
                for ($i = 1; $i < $len; $i++) {
                    $ascii = ord($data[$i]);
                    if ($ascii >= 65 && $ascii <= 90) {
                        $new_str .= '_' . chr($ascii + 32);
                    } else {
                        $new_str .= $data[$i];
                    }
                }
                return $new_str;
            } elseif (is_array($data)) {
                foreach ($data as $k => $v) {
                    // 处理多维数组的情况
                    if (is_array($v)) {
                        // 如果是多维数组,递归转换.(如果下标是数字的值又是一个数组,那么仍需要递归转换,数字保留不变)
                        $_k = is_numeric($k) ? $k : self::camel2Underline($k);
                        $data[$_k] = self::camel2Underline($v);
                        if ($k !== $_k) unset($data[$k]); // 数组下标为数字的不能删除,因为$k == $_k
                    } else {
                        // 数组下标如果是数字,则不处理
                        if (is_numeric($k)) {
                            continue;
                        }
                        $_k = self::camel2Underline($k);
                        $data[$_k] = $data[$k];
                        if ($k !== $_k) unset($data[$k]); // 数组下标如果是全小写,例如:uid,是不能删除的。要保留
                    }
                }
                return $data;
            } else {
                // throw new \Exception('不支持的数据类型:' . gettype($data));
                return $data;
            }
        }
    
        // 测试
        public static function testUnderline2Camel()
        {
            $str1 = '_title';
            $str2 = 'title_';
            $str3 = '_title_';
            $str4 = 'title_boy__girl_中文_title';
            $data = ['img_url' => 'dssd', 'user_name' => 'dfd', 1 => 'asd', 2 => ['u_a' => 'xcz'], 'user_bb' => ['aa_cc' => 'xxx', 'cc_dd' => ['ee_ff' => 'fds']]];
            $data = ['img_url' => 'dssd', 'username' => 'dfd', 1 => 'asd', 2 => ['u_a' => 'xcz'], 'user_bb' => ['aa_cc' => 'xxx', 'cc_dd' => ['ee_ff' => 'fds']]];
            dump(Util::underline2Camel($str1));
            dump(Util::underline2Camel($str2));
            dump(Util::underline2Camel($str3));
            dump(Util::underline2Camel($str4));
            dump(Util::underline2Camel($data));
            dump(Util::camel2Underline(Util::underline2Camel($data)));
            dump(Util::camel2Underline(Util::underline2Camel($str4)));
            dump(Util::camel2Underline(Util::underline2Camel($str3)));
    
            die();
        }
    }
    最终版