片段1日期时间字符串分析

日期时间字符串分析
Date Format
php date 函数 格式化 2024-08-09 Friday 这样的时间戳

在PHP中,你可以使用date函数来格式化日期和时间。如果你想要将日期2024-08-09格式化为2024-08-09 Friday这样的格式,你可以使用以下代码:

$timestamp = strtotime('2024-08-09'); // 将日期字符串转换为时间戳
$formatted_date = date('Y-m-d l', $timestamp); // Y-m-d 表示年-月-日,l 表示完整的星期几
echo $formatted_date; // 输出格式化后的日期

这里的strtotime函数用于将日期字符串转换为Unix时间戳。date函数的第一个参数是格式化字符串,Y-m-d表示年-月-日,l(小写的L)表示星期几的完整名称。第二个参数是时间戳。

运行这段代码后,你将得到输出:2024-08-09 Friday

片段2 数组分组操作

数组分组操作
Array groupBy
laravel 的 arr 函数 ,将 多维数组按其中的属性 date 分组

在 Laravel 中,你可以使用集合(Collection)提供的 groupBy 方法来按某个属性对数组进行分组。如果你有一个多维数组,并且想要根据每个子数组中的 date 属性进行分组,你可以使用以下代码:

use Illuminate\Support\Arr;

$array = [
    ['name' => 'Event 1', 'date' => '2024-08-09'],
    ['name' => 'Event 2', 'date' => '2024-08-09'],
    ['name' => 'Event 3', 'date' => '2024-08-10'],
    // ... 更多事件
];

$grouped = Arr::groupBy($array, 'date');

print_r($grouped);

这段代码会创建一个新的数组,其键是日期,值是具有相同日期的所有子数组。

如果你的数组结构更复杂,例如每个子数组是一个包含多个属性的对象,你可以使用匿名函数来指定分组的键:

use Illuminate\Support\Arr;

$array = [
    ['name' => 'Event 1', 'date' => '2024-08-09', 'other' => 'info1'],
    ['name' => 'Event 2', 'date' => '2024-08-09', 'other' => 'info2'],
    ['name' => 'Event 3', 'date' => '2024-08-10', 'other' => 'info3'],
    // ... 更多事件
];

$grouped = Arr::groupBy($array, function ($item) {
    return $item['date'];
});

print_r($grouped);

在这个例子中,groupBy 方法接受一个匿名函数作为参数,该函数返回用于分组的键。在这个函数中,我们返回每个子数组的 date 属性。

请确保你已经正确地引入了 Arr 类,并且你的 Laravel 环境已经设置好。如果你没有使用 Laravel 框架,你需要手动实现类似的分组逻辑。

片段3 异常处理

API 返回值结构修改
自定义 401 错误返回

在 Laravel 8 中自定义 API 的 401 错误返回格式,你可以通过修改 app/Exceptions/Handler.php 文件中的 unauthenticated 方法来实现。以下是具体的步骤和代码示例:

  1. 打开 Handler.php 文件: 找到 app/Exceptions/Handler.php 文件并打开它。

  2. 重写 unauthenticated 方法: 在 Handler 类中重写 unauthenticated 方法,以自定义 401 错误响应的格式。以下是修改后的代码示例:

    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return $request->expectsJson()
            ? response()->json([
                'code' => 0,
                'message' => $exception->getMessage(),
                'data' => null
            ], 401)
            : redirect()->guest($exception->redirectTo() ?? route('login'));
    }
    

    在这段代码中,当捕获到 AuthenticationException 异常时,如果请求期望的是 JSON 响应,则返回一个包含自定义数据格式的 JSON 响应,状态码为 401。如果不是 JSON 请求,则重定向到登录页面。

  3. 保存并测试: 保存修改后的 Handler.php 文件,并进行测试以确保自定义的 401 错误响应格式生效。

通过上述步骤,你可以自定义 Laravel 8 中 API 的 401 错误返回格式,使其符合你的应用程序需求。这样的自定义可以帮助你更好地控制 API 响应的数据结构,提高 API 的可用性和用户体验。

自定义 API 的 401 错误返回格式

我根据项目需要,加了 msg 的多语言翻译:

    //自定义 API 的 401 错误返回格式
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return $request->expectsJson()
            ? response()->json([
                'code' => 401,
                'msg' => __('msgs.' . $exception->getMessage()),
                'lang' => app()->getLocale(),
                'data' => null
            ], 401)
            : redirect()->guest($exception->redirectTo() ?? route('login'));
    }


    // 默认异常字符串定义在语言包文件:resources\lang\zh_CN\msgs.php
    return [
        'Unauthenticated.' => '未通过身份验证',
        'marked' => '标记成功',
    ];

片段4 command文件创建

Artisan 命令
生成一个命名为TransCol的 Artisan 命令,它接收参数表名,字段名1,字段名2,功能为调用第三方翻译API,将字段名1的内容翻译为字段名2;跳过字段名2所在行不为空的记录;

 

要创建一个名为 TransCol 的 Artisan 命令,你需要执行以下步骤:

  1. 创建命令: 使用 Artisan 命令行工具创建一个新的命令:

    php artisan make:command TransCol
    
  2. 编辑命令: 这个命令会在你的 app/Console/Commands 目录下创建一个名为 TransCol.php 的文件。打开这个文件并编辑它,以便接收参数并执行翻译逻辑。

    <?php
    
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use DB;
    use Exception;
    
    class TransCol extends Command
    {
        protected $signature = 'translate:columns {table : The table name} {field1 : The field name to translate from} {field2 : The field name to translate to}';
        protected $description = 'Translate content from one column to another using a third-party API';
    
        public function handle()
        {
            $table = $this->argument('table');
            $field1 = $this->argument('field1');
            $field2 = $this->argument('field2');
    
            // 检查字段2是否为空,如果非空则跳过
            DB::table($table)->where($field2, '!=', '')->get(); // 这会获取所有字段2非空的记录,但我们不会对它们做任何操作
    
            // 获取所有字段1非空的记录
            $records = DB::table($table)->where($field2, '=', '')->get();
    
            foreach ($records as $record) {
                try {
                    // 调用第三方翻译API,这里需要替换成实际的API调用代码
                    $translatedText = $this->translateUsingThirdPartyApi($record->$field1);
    
                    // 更新字段2的内容
                    DB::table($table)->where($field1, $record->$field1)->update([$field2 => $translatedText]);
                } catch (Exception $e) {
                    $this->error("Error translating record with {$field1} = {$record->$field1}: " . $e->getMessage());
                }
            }
    
            $this->info('Translation completed successfully.');
        }
    
        protected function translateUsingThirdPartyApi($text)
        {
            // 这里应该是调用第三方翻译API的代码,返回翻译后的结果
            // 以下代码仅为示例,需要替换成实际的API调用
            $apiUrl = 'https://api.example.com/translate';
            $data = [
                'q' => $text,
                'source' => 'en',
                'target' => 'fr'
            ];
    
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $apiUrl);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
    
            $response = curl_exec($ch);
            curl_close($ch);
    
            // 解析响应并返回翻译后的文本
            $result = json_decode($response, true);
            return $result['translatedText'] ?? '';
        }
    }
    
  3. 注册命令: 如果你的命令不在默认的 Kernel.php 文件的 $commands 数组中,你需要在 app/Console/Kernel.php 文件中注册你的命令:

    protected $commands = [
        Commands\TransCol::class,
    ];
    
  4. 运行命令: 使用以下 Artisan 命令行调用你的命令,并传递所需的参数:

    php artisan translate:columns your_table_name field1 field2
    

请注意,你需要将 translateUsingThirdPartyApi 方法中的代码替换成实际的第三方翻译 API 调用代码,并处理 API 响应。此外,确保你的数据库连接配置正确,并且你有足够的权限来更新数据库记录。

修改后符合实际需求的代码

将 目标语言 参数 target放到最后,并且第三方翻译 API放到 Services 目录中

<?php

namespace App\Console\Commands;

use App\Services\Translate;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class TransCol extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'trans:col {table : The table name} {field1 : The field name to translate from} {field2 : The field name to translate to} {target : The target language}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'translate table columns using a third-party API';

    protected $transService;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct(Translate $translate)
    {
        parent::__construct();
        $this->transService = $translate;
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        //dd($this->transService->translateByBaidu('学历'));
        $table = $this->argument('table');
        $field1 = $this->argument('field1');
        $field2 = $this->argument('field2');
        $target = $this->argument('target');

        // 检查字段2是否为空,如果非空则跳过
        //DB::table($table)->where($field2, '!=', '')->get(); // 这会获取所有字段2非空的记录,但我们不会对它们做任何操作

        // 获取所有字段1非空的记录
        $records = DB::table($table)->where($field2, '=', '')->get();

        foreach ($records as $record) {
            try {
                // 调用第三方翻译API,这里需要替换成实际的API调用代码
                $translatedText = $this->transService->translateByBaidu($record->$field1, $target);

                // 更新字段2的内容
                DB::table($table)->where($field1, $record->$field1)->update([$field2 => $translatedText]);
                $this->info("√ with {$field1} = {$record->$field1} to {$translatedText}");
                //sleep(0.2);
            } catch (\Exception $e) {
                $this->error("❌ Error translating record with {$field1} = {$record->$field1}: " . $e->getMessage());
            }
        }

        $this->info('Translation completed successfully.');
        return 0;
    }
}

百度翻译 API 调用

<?php

namespace App\Services;

class Translate
{
    /**
     * 百度翻译
     * @param mixed $text
     * @param mixed $targetLang
     * @param mixed $sourceLang  default zh
     * @throws \Exception
     * @return mixed
     */
    public function translateByBaidu($text, $targetLang ='en', $sourceLang = 'zh')
    {
        // 百度翻译API的URL
        $apiUrl = 'https://fanyi-api.baidu.com/api/trans/vip/translate';

        // 请替换为你的百度翻译应用的API Key和Secret Key
        $apiKey = config('setting.baidu_key');
        $secretKey = config('setting.baidu_sec');

        // 准备请求参数
        $salt = rand(10000, 99999);
        $data = [
            'q'     => $text, // 要翻译的文本
            'from'  => $sourceLang, // 源语言
            'to'    => $targetLang, // 目标语言
            'appid' => $apiKey, // API Key
            'salt'  => $salt, // 随机数
            'sign'  => md5($apiKey . $text . $salt . $secretKey), // 签名
        ];


        $result = $this->curlExec($apiUrl, $data);
        // 检查是否有错误
        if (isset($result['error_code'])) {
            throw new \Exception("Error from Baidu Translate API: " . $result['error_msg']);
        }

        // 返回翻译后的文本
        return $result['trans_result'][0]['dst'] ?? '';
    }

    private function curlExec($apiUrl, $data)
    {
        // 将数据转换为查询字符串
        $dataString = http_build_query($data);

        // 初始化cURL会话
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);

        // 执行cURL请求
        $response = curl_exec($ch);
        curl_close($ch);

        // 解析响应
        return json_decode($response, true);
    }
}