A Quick Way to Test Laravel Database Connections

You can use Tinker to verify if your database connection is working:

php artisan tinker

Then inside Tinker, run:

DB::connection()->getPdo();

If the connection succeeds, you’ll get back PDO instance details. If it fails, you’ll see the actual error message (usually something helpful like credentials issues or host unreachable).

一图看懂OAuth 2.0协议

授权码授权模式和隐式授权模式的区别:

  • 授权码授权模式,把access token存储在服务器端(session或redis里)
  • 隐式授权模式,把access token直接返回给客户端并存储,无需交换授权码。此授权模式最常用于无法安全存储客户端凭据的JavaScript或移动应用程序

laravel-phone包实现电话号码验证、格式转换等功能

相信你的系统中也一定会有手机注册以及发送短信验证码的功能。那么验证用户填写的手机号是否规范合法就是我们完成后续功能的第一步。propaganistas/laravel-phone包为我们提供了非常强大且可靠的电话验证功能,并且适用于全球所有国家的号码验证。

安装

composer require propaganistas/laravel-phone

配置

服务提供者会被 Laravel 自动发现。在语言目录lang中,为每个 validation.php 语言文件添加一条额外的翻译:

'phone' => 'The :attribute field must be a valid number.',

在线工具网站

https://laravel-phone.herokuapp.com用于测试Laravel-Phone包中的电话号码验证组件。

验证请求字段

你可以在验证规则数组中使用phone关键字,或者使用 Propaganistas\LaravelPhone\Rules\Phone规则类来以更具表现力的方式定义规则。 要限制国家/地区,你可以明确指定允许的国家/地区的代码:

'my_input'       => 'phone:US,BE',
// 'my_input'    => (new Phone)->country(['US', 'BE'])

或者为了使功能更加灵活,还可以与另一个包含国家/地区代码的数据字段进行匹配。例如,要求用户的电话号码与用户提供的居住国家/地区匹配。请确保国家/地区字段的名称与电话号码字段的名称相同,但附加”_country”后缀以便laravel-phone包自动识别:

'my_input'            => 'phone',
// 'my_input'         => (new Phone)
'my_input_country'    => 'required_with:my_input',

或者将自定义的国家/地区字段名称作为参数传递给验证器:

'my_input'            => 'phone:custom_country_field',
// 'my_input'         => (new Phone)->countryField('custom_country_field')
'custom_country_field'  => 'required_with:my_input',

注意:国家代码应符合ISO 3166-1 alpha-2标准。

为了支持除白名单国家/地区之外的任何有效国际格式的电话号码,请使用INTERNATIONAL参数。当你预期接收来自特定国家/地区的本地格式号码,但同时也希望接受任何其他正确输入的国外号码时,此功能会非常有用:

'my_input'            => 'phone:INTERNATIONAL,BE',
// 'my_input'         => (new Phone)->international()->country('BE')

要指定电话号码类型的约束,请将允许的类型附加到参数后面,例如:

'my_input'       => 'phone:mobile',
// 'my_input'    => (new Phone)->type('mobile')
// 'my_input'    => (new Phone)->type(libphonenumber\PhoneNumberType::MOBILE)

最常见的类型是移动电话mobile和固定电话fixed_line,但你可以随意使用此处定义的任何电话号码类型。

在电话号码类型名称前加上感叹号即可将其列入黑名单。请注意,你不能同时使用白名单和黑名单:

'my_input'       => 'phone:!mobile',
// 'my_input'    => (new Phone)->notType('mobile')
// 'my_input'    => (new Phone)->notType(libphonenumber\PhoneNumberType::MOBILE)

你还可以使用LENIENT参数启用宽松验证。启用宽松验证后,系统只会检查数字的长度,而不会检查实际的运营商模式:

'my_input'       => 'phone:LENIENT',
// 'my_input'    => (new Phone)->lenient()

模型属性转换(cast)

为了方便对Eloquent模型属性进行自动类型转换,我们提供了两个转换类:

use Illuminate\Database\Eloquent\Model;
use Propaganistas\LaravelPhone\Casts\RawPhoneNumberCast;
use Propaganistas\LaravelPhone\Casts\E164PhoneNumberCast;

class User extends Model
{
    public $casts = [
        'phone_1' => RawPhoneNumberCast::class.':BE',
        'phone_2' => E164PhoneNumberCast::class.':BE',
    ];
}

这两个类都会自动将数据库中的值转换为PhoneNumber对象,以便在你的应用程序中进一步使用:

$user->phone // PhoneNumber object or null

在设置值时,它们都接受字符串值或PhoneNumber对象。RawPhoneNumberCast会将数据库值更改为原始输入号码,而E164PhoneNumberCast会将格式化的E.164电话号码写入数据库。

对于RawPhoneNumberCast类,需要指定电话号码所属国家/地区,才能正确地将原始号码解析为PhoneNumber对象。对于E164PhoneNumberCast类,如果待设置的值并非已采用某种国际格式,则也需要指定电话号码所属国家/地区,才能正确地转换该值。

这两个类以相同方式接受类型转换参数:

  • 如果存在名称相似但后缀为”_country”的属性(例如phone_country),则类型转换器会自动检测并使用该属性
  • 提供另一个属性的名称作为类型转换参数
  • 提供一个或多个国家/地区代码作为类型转换参数
public $casts = [
    'phone_1' => RawPhoneNumberCast::class.':country_field',
    'phone_2' => E164PhoneNumberCast::class.':BE',
];

重要提示:这两种类型转换都需要有效的电话号码才能顺利地进行PhoneNumber对象的转换。请在将电话号码设置到模型之前进行验证。有关如何验证电话号码,请参阅上节“验证请求字段”。

⚠️ 属性赋值和E164PhoneNumberCast

由于E164PhoneNumberCast的特性,如果电话号码不是国际格式,则需要提供有效的国家/地区代码。由于Laravel在设置属性时会立即执行类型转换,因此请务必在设置电话号码属性之前设置国家/地区代码属性。否则,E164PhoneNumberCast将遇到空的国家/地区代码值并抛出意外异常。

// 错误
$model->fill([
    'phone' => '012 34 56 78',
    'phone_country' => 'BE',
]);

// 正确
$model->fill([
    'phone_country' => 'BE',
    'phone' => '012 34 56 78',
]);

// 错误
$model->phone = '012 34 56 78';
$model->phone_country = 'BE';

// 正确
$model->phone_country = 'BE';
$model->phone = '012 34 56 78';

实用电话号码类PhoneNumber

电话号码可以封装在Propaganistas\LaravelPhone\PhoneNumber类中,从而为其添加实用的方法。在视图中或保存到数据库时,可以直接引用这些对象,它们会优雅地降级为E.164格式。

use Propaganistas\LaravelPhone\PhoneNumber;

(string) new PhoneNumber('+3212/34.56.78');                // +3212345678
(string) new PhoneNumber('012 34 56 78', 'BE');            // +3212345678

或者,你可以使用phone()辅助函数。它会返回一个Propaganistas\LaravelPhone\PhoneNumber实例,如果提供了$format参数,则返回格式化后的字符串:

phone('+3212/34.56.78');                // PhoneNumber instance
phone('012 34 56 78', 'BE');            // PhoneNumber instance
phone('012 34 56 78', 'BE', $format);   // string

格式化号码

可以多种方式格式化PhoneNumber实例:

$phone = new PhoneNumber('012/34.56.78', 'BE');

$phone->format($format);       // 见libphonenumber\PhoneNumberFormat
$phone->formatE164();          // +3212345678
$phone->formatInternational(); // +32 12 34 56 78
$phone->formatRFC3966();       // tel:+32-12-34-56-78
$phone->formatNational();      // 012 34 56 78

// 格式化后,即可直接从提供的国家/地区拨打该号码
$phone->formatForCountry('BE'); // 012 34 56 78
$phone->formatForCountry('NL'); // 00 32 12 34 56 78
$phone->formatForCountry('US'); // 011 32 12 34 56 78

// 格式化后的号码在手机上可以直接点击,然后可以用手机直接从指定的国家/地区拨打该号码
$phone->formatForMobileDialingInCountry('BE'); // 012345678
$phone->formatForMobileDialingInCountry('NL'); // +3212345678
$phone->formatForMobileDialingInCountry('US'); // +3212345678

号码信息

获取一些关于该号码的信息:

$phone = new PhoneNumber('012 34 56 78', 'BE');

$phone->getType();              // libphonenumber\PhoneNumberType::FIXED_LINE
$phone->isOfType('fixed_line'); // true    (or use $phone->isOfType(libphonenumber\PhoneNumberType::FIXED_LINE) )
$phone->getCountry();           // 'BE'
$phone->isOfCountry('BE');      // true

等值比较

比较两个号码相同还是不同:

$phone = new PhoneNumber('012 34 56 78', 'BE');

$phone->equals('012/34.56.76', 'BE')       // true
$phone->equals('+32 12 34 56 78')          // true
$phone->equals( $anotherPhoneObject )      // true/false

$phone->notEquals('045 67 89 10', 'BE')    // true
$phone->notEquals('+32 45 67 89 10')       // true
$phone->notEquals( $anotherPhoneObject )   // true/false

数据库注意事项

免责声明:不同应用程序处理电话号码的方式各不相同。因此,以下内容仅供参考,旨在启发思考;我们不提供相关技术支持。

将电话号码存储在数据库中一直是一个值得探讨的问题,而且并没有一劳永逸的解决方案(没有银弹)。一切都取决于你的应用程序需求。以下是一些需要考虑的因素,以及一个实现建议。你理想的数据库设置可能需要结合以下列出的一些要点。

中国国内注册TikTok显示“网络不稳定”的解决方法

在中国国内想要成功注册TikTok,需要满足以下前提条件:

1 移除SIM卡。只要TikTok检测到你的手机里有中国SIM卡,它就不让使用!

2 卸载字节跳动公司的所有国内App,例如抖音、今日头条等。以防止被TikTok识别为国内环境。

3 更改手机的系统语言和时区为米国。

4 开启VPN全局代理,代理IP设置为米国的IP。

5 使用米国的手机号码,例如Google Voice,进行注册TikTok。

以上以米国的工具为例,你使用其他不是中国的国家的工具也行。

通过127.0.0.1可以正常访问到虚拟机中的网站,但通过hosts文件中配置的域名访问就报503错误,原因是被v2rayN干扰

我使用virtualbox,主机是Windows 11,虚拟机是Ubuntu 24,配置了端口映射8086到8086。

网站在Ubuntu 24虚拟机里可以通过test.com:8086正常访问到,也可以通过127.0.0.1:8086正常访问到,这说明我的Nginx配置没有问题。我在Windows 11的C:\Windows\System32\drivers\etc\hosts里面配置了:
127.0.0.1 test.com
我在Windows 11里使用127.0.0.1:8086可以正常访问到Ubuntu 24虚拟机中的这个网站,但是使用test.com:8086访问不到,报503错误。

原因是被v2rayN干扰,清除系统代理后,使用test.com:8086就能正常访问虚拟机中的这个网站。更好解决方法是,打开v2rayN的设置->参数设置->系统代理设置窗口,填入要被v2rayN忽略的网站地址。这样这些网站就不会被v2rayN干扰了,同时我们也能在Windows里能正常使用v2rayN。

在Rocky 10虚拟机中安装VirtualBox增强功能时遇到“找不到内核头文件”报错的解决方法

1. 启用 EPEL 仓库并安装必要软件包

# 启用 EPEL 仓库
sudo dnf install epel-release

# 安装内核开发头文件和相关工具
sudo dnf install kernel-devel kernel-headers gcc make perl dkms
sudo dnf install kernel-modules-extra

2. 检查内核版本匹配是否匹配开发包的版本

# 查看当前运行的内核版本
uname -r

# 查看已安装的内核开发包版本
rpm -qa | grep kernel-devel
rpm -qa | grep kernel-headers

# 如果版本不匹配,安装对应版本的开发包
sudo dnf install kernel-devel-$(uname -r) kernel-headers-$(uname -r)

3. 安装 VirtualBox 增强功能

安装 VirtualBox 增强功能之前记得先更新一下系统:

sudo dnf update

方法一:通过VirtualBox菜单安装

  1. 启动虚拟机
  2. 在 VirtualBox 菜单中选择 设备 → 插入客户机增强功能 CD 镜像
  3. 挂载 CD 后运行安装

方法二:手动输入命令安装

# 挂载增强功能 CD
sudo mkdir -p /mnt/cdrom
sudo mount /dev/cdrom /mnt/cdrom

# 进入 CD 目录并安装
cd /mnt/cdrom
sudo ./VBoxLinuxAdditions.run

# 卸载 CD
sudo umount /mnt/cdrom

Common Google Chrome Keyboard Shortcuts

Window and Tab Shortcuts

Ctrl+N Open a new window

Ctrl+T Open a new tab

Ctrl+W or Ctrl+F4 Close the current tab

Alt+F4 Close the current window

Hold Ctrl and click a link (or middle-click with mouse) Open link in a new tab

Ctrl+K or Ctrl+E Focus the address bar to enter search text

Ctrl+D Bookmark the current tab

Ctrl+Shift+D Bookmark all open tabs in the current window to a new folder

F11 Toggle full screen

F12 or Ctrl+Shift+I Open Developer Tools

Shift+Esc Open Task Manager to view CPU usage, memory, etc. per tab

Alt+F or Alt+E Open the “Tools” menu for customizing and controlling Chrome settings

Ctrl+Shift+B Toggle the bookmarks bar

Ctrl+H Open the “History” page

Ctrl+Shift+Delete Open the “Clear browsing data” dialog

Ctrl+J Open the “Downloads” page

Webpage Shortcuts

Ctrl+P Print the current page

Ctrl+S Save the current page

F5 or Ctrl+R Reload the current page (refresh)

Ctrl+F5 or Shift+F5 Reload the current page, ignoring cache (hard refresh)

Esc Stop loading the current page

Ctrl+F Open the find bar

Ctrl+U View the page source code

Hold Ctrl and scroll mouse wheel up/down Zoom in/out on all page content

Ctrl+0 Reset page zoom to normal size

Home Scroll to the top of the page

End Scroll to the bottom of the page

Hold Shift and scroll mouse wheel Scroll horizontally on the page

Address Bar Shortcuts

Ctrl+Enter (When cursor is in address bar) Add “www.” and “.com” around input and open the URL

Long-press (hold left mouse button) on “Back” or “Forward” button Show a dropdown list of recent page URLs; alternatively, right-click for the same menu

谷歌浏览器常用快捷键

窗口和标签页快捷键
Ctrl+N 打开一个新窗口
Ctrl+T 打开新标签
Ctrl+W或Ctrl+F4 关闭当前标签页
Alt+F4 关闭当前窗口

按住Ctrl键点击链接(或使用鼠标中键点击) 在新标签页打开链接
Ctrl+K或Ctrl+E 地址栏输入要搜索的文本
Ctrl+D 将当前标签页保存为书签
Ctrl+Shift+D 将当前窗口打开的全部标签页以书签方式保存在一个新建文件夹里
F11 全屏

F12或Ctrl+Shift+I 打开开发者工具
Shift+Esc 打开任务管理器,可以查看每个标签页CPU使用率,内存占用等
Alt+F或Alt+E 打开“工具”菜单,用该菜单可自定义和控制Chrome浏览器中的设置
Ctrl+Shift+B 打开和关闭书签栏
Ctrl+H 打开“历史记录”页面
Ctrl+Shift+Delete 打开“清除浏览数据”对话框
Ctrl+J 打开“下载内容”页面

网页快捷键
Ctrl+P 打印当前网页
Ctrl+S 保存当前网页
F5或Ctrl+R 重新载入当前网页,即刷新当前页面
Ctrl+F5或Shift+F5 重新加载当前页面,忽略缓存的内容,即强制刷新当前页面
Esc 停止载入当前网页
Ctrl+F 打开查找栏
Ctrl+U 打开当前网页的源代码
按住Ctrl键并向上滚动鼠标滚轮放大或向下滚动鼠标滚轮缩小网页上的所有内容
Ctrl+0 将网页上的所有内容都恢复到正常大小
Home 转至网页顶部
End 转至网页底部
按住Shift键的同时滚动鼠标滚轮 在网页上横向滚动

地址栏快捷键
Ctrl+Enter (当光标位于地址栏中时)在地址栏的输入内容前后分别加上www.和.com,并打开网址
长按(不要放开鼠标左键)“后退”或“前进”按钮,即可显示刚才浏览过的页面地址的列表。你也可以右击“后退”或“前进”按钮来弹出该下拉菜单