Categories
未分类

解决导出的 Mac “图书” 无法打开问题

最近遇到一个问题,就是从 Mac Apple “图书” 应用里导出(拖拽)的电子书,第三方软件无法打开。因为导出的并不是标准的 EPUB 格式文件,换句话说,不是一个独立的后缀为 .epub 的文件,而是一个 macOS 的 EPUB 包(文件夹)。举个例子,如下: 现在的解决办法是,将这个文件夹按照一定标准,压缩转换为文件,方法如下: 核心是通过 “终端” 执行如下命令: 新电子书.epub 代表转换后的文件。 具体过程如下,先看下当前所在目录: 进入旧电子书目录,依次执行两个命令: 执行完成后: 参考资料: ePub Zip/Unzip AppleScript application for Mac OS X – MobileRead Forums 扫码阅读和分享

Categories
未分类

Java 中 Date 和 LocalDateTime 互相转换

LocalDateTime 转换为 Date 看示例: 输出结果: 简单分析下: 先调用 LocalDateTime 的 atZone 方法(参数为系统默认时区),获取带时区信息的 ZonedDateTime 时间对象,然后转换为 Instant 瞬时对象。最后通过 Date 的 from 方法创建 Date 对象。 Date 转换为 LocalDateTime 看示例: 输出结果: 简单分析下: 先转换 Date 为 Instant 瞬时对象,再调用 LocalDateTime 的 ofInstant 方法(第二个参数为系统默认时区)即可。 其它 完整源码,请参阅:LocalDatetimeAndDate.java。 (全文完) 扫码阅读和分享

Categories
PHP

PHP 通过 Redis NX 特性实现独占锁

对于简单的业务,我们可以通过单实例的 Redis 实现一个全局独占锁。笔者以 PHP 为例,实现一个加锁类。 实现原理 对于 Redis 的 SET 命令,支持 NX 特性,官方解释为:Only set the key if it does not already exist。也就是,当 key 不存在时设置成功后,才会返回 OK,否则返回 nil。这样,当多个并发请求设置 key 时,只有一个会成功。 然后,结合 EX 过期时长,指定加锁时长,即过期后自动释放锁。再通过指定 key 的值为随机 Token,来保证当前操作不会错误的释放其它业务请求的锁。详见下文实例。 SET 用法如下: 具体实现 实例的完整源码,放到了:https://github.com/xingchaovv/php-example/tree/master/src/RedisLocker,请参考使用。源码基于 PHP 8。 方法 lock 实现 方法 unlock 实现 用法 (完) 扫码阅读和分享

Categories
未分类

PHP 8 新特性:从构造函数直接声明属性

在 PHP 8 之前,自定义的类中,对于一个属性的初始化和使用过程是这样的。如下: 在 PHP 8 之后,我们可以直接在构造函数中将入参声明为类属性,并指明访问权限和变量类型。如下: 通过代码“__construct(private string $name)”,声明了属性变量 name,指明访问权限为 private,类型为 string。当通过构造函数构建实例时,直接对 name 进行了赋值。 (完) 扫码阅读和分享

Categories
PHP

PHP 8 新特性: Nullsafe 操作符(空安全)

PHP 8 新增了 Nullsafe 操作符(空安全):?->,顾名思义,以一种安全的方式操作可能为 null 的对象。以此可以简化对于 null 值的逻辑判断。 准备 我们先准备一些类和实例。如下: 以往实现 不严谨的程序员,想获取 user1 的 total 信息时,可能会直接取值。如下: 当然,程序会直接报错: 有点经验的程序员这么做(实际会经常这么做): 当然,实际中还需要对 fanInfo 等做一系列判断,也可能无法避免一些嵌套的判断。 Nullsafe 实现 现在有了 Nullsafe 操作符,我们可以直接这样用: 输出结果: 当然 user1 为 null 时,表达式直接返回了 null,且不再会调用属性 fanInfo 和后续操作。下面详细介绍求值策略。 短路求值策略 Nullsafe 操作符遵循的是完全短路(Full Short Circuiting)的求值策略。 举例说明: 当 a 为 null 时,方法 b 不会被调用,$foo 被赋值为 null。 当 a 为 null […]

Categories
PHP

PHP 8 函数 str_contains:检查是否包含子字符串

PHP 8 中新增了一个函数 str_contains,专门用于检查一个字符串是否包含了另外一个字符串。很大原因是 strpos 函数不够直观且容易出错。这里简单介绍下。 原型如下: 如果字符串 $haystack 中包了字符串 $needle,则返回 true,否则为 false。检查时大小写敏感。 看下例子: 输出为: 因为大小写敏感,第二行返回 false。 如同第三行,当目标字符串为空字符串时,结果总是为 true。 参考资料 str_contains 扫码阅读和分享

Categories
PHP

PHP 8 新特性:联合类型

定义 在 PHP 8 中,定义函数参数的类型时,可以指定多种类型;也就是允许它的值为这些类型中的一种;我们称这种类型为联合类型(Union Types)。 一般语法 联合类型的语法格式为: 举第一个例子 🌰: 上文中 int|float 指明了参数 $score 为联合类型,它可以是 int 类型 或 float 类型。 输出结果为: 上文中,因为传递了不允许的类型 string,直接抛出 TypeError 类型的错误。 ?Type 语法 我们可以指定类型为某个 Class 或者 null,比如 DateTime|null,简化写法为 ?Type。 另外,不支持单独使用类型 null。 举第二个例子 🌰: 输出为: 伪类型 false 可以在联合类型使用伪类型 false,比如 string|false。另外,不支持单独使用类型 false。暂不支持伪类型 true(保留关键字)。 参考资料 扫码阅读和分享

Categories
PHP

PHP 8 新特性:命名参数

PHP 8 新增了语言特性:命名参数(Named Arguments)。以往只能按照函数定义的顺序传递参数,现在可以指定参数名称自定义顺序。并且可以跳过带默认值的参数。 正文 我们举例说明。 我们先定义一个函数,接受三个参数。函数中直接将实际接收到的参数打印出来。代码如下: 在 PHP 7 中,我们调用函数时,不允许带参数名称。如下: 在 PHP 8 中,我们可以像下面这样。 话外 除了 PHP,还有哪些语言支持命名参数呢? Python:见《Expressions -> Calls》、《Python Keyword Arguments》 C# 4:见《命名实参和可选实参》 Swift:见《Functions -> Functions With Multiple Parameters》 参考资料: (完) 扫码阅读和分享

Categories
PHP

PhpSpreadsheet(PHP Excel 类库)正确显示身份证号的解决办法

PhpSpreadsheet(原 PHPExcel)是 PHP 中最流行的电子表格软件(如 Excel)的处理类库,可以读取、写入 Excel 数据等,经常用于业务系统的报表导出等。 问题复现 在使用过程中,经常遇到的问题是,无法正常显示身份证号。我们看下实例: 源文件:sheet1.php 终端下执行下:% php sheet1.php,保存到了文件 users.xlsx,查看结果: 可见,莱德等小狗狗的身份证号,默认被当作了数字数据类型。 原因分析 这是因为在通过 fromArray 间接或 或直接使用 setCellValue 方法时,未指定数据类型。这时,PhpSpreadsheet 使用值绑定器(Value Binder)自动将传入的参数转换为合适的 Cell 数据类型。具体源码实现,见默认的值绑定器是 DefaultValueBinder。此处身份证号虽然是原生 string,但符合类对数字的定义,处理成了数字数据类型。 解决办法:使用 setCellValueExplicit 我们在设置值时使用 setCellValueExplicit 方法指定类型。 天天的身份证号已经正常显示。 若希望类似 fromArray 批量写入数据,可自行实现一个迭代处理。 解决办法:自定义值绑定器 另外一种办法是实现自定义的值绑定器类。 直接看实现源码: 结果 实现说明: 这里自定义了类 MyValueBinder,扩展了 DefaultValueBinder,“重写”了方法 dataTypeForValue。 参考资料 文档 Accessing cells (全文完) 扫码阅读和分享

Categories
未分类

PHP 函数 pathinfo 用法详解

介绍 pathinfo 函数可以解析和返回指定文件的路径信息。比如文件目录路径、扩展名等。 函数原型 pathinfo (string $path[, int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME]) : mixed 第一个参数,必传,文件路径。 第二个参数,选传,指定返回的元素。未指定时,全部返回。 返回值,根据第二个参数选项,返回指定元素的字符串,或返回一个数组,包含所有的元素。 用法示例 源码一 $myAccessLog = “/data/www/xingchaovv-com/access.log”; var_dump(pathinfo($myAccessLog)); 执行结果 array(4) { [“dirname”]=> string(24) “/data/www/xingchaovv-com” [“basename”]=> string(10) “access.log” [“extension”]=> string(3) “log” [“filename”]=> string(6) “access” } pathinfo 直接返回文件所有信息,其中 dirname 为文件所在目录路径;basename 为文件基础名称,即文件名;extension 为文件扩展名,filename 为文件不含后缀名称。 源码二 var_dump(pathinfo($myAccessLog, PATHINFO_DIRNAME)); 执行结果 […]