看英语字幕视频学英语app开发日记 php
产品介绍
这是一款通过看视频看英语字幕来学习英语的app,根据的外语学习理论是可理解性输入。进行大量的可以理解性的英语内容输入,可以实现有效的外语学习,不需要枯燥的背单词,学语法。
网址:https://eng.devxiang.com/videoDetail/10
(仅支持手机端浏览器访问。)
笔者是一个后端程序员和这个产品的发起人,和我一起合作的还有一名vuejs前端开发者。
6月26日
- 完成了单词词库的构建,有49000多个英语单词。使用了github上的开源词库。导进mysql数据表。写成接口,现在打算开放给大家免费使用,如果有需要的话,欢迎使用。
单词查询接口文档
https://apifox.com/apidoc/shared-9931ba6d-69fc-471c-a874-aff60ee3bbcb
- 完成了视频详情接口,前端完全了字幕独立加载,按时间展示,支持分词点击查询单词中文意思。但目前只支持手机浏览器访问,pc端浏览器还没有做兼容。
按敏捷开发原则,快速开发出产品原型,最小可使用的版本。第一版已经支持视频播放,字幕独立展示,可以点击查询。算是可以使用的了。
3.未来功能安排,
3.1 通过ai接口 视频的音频识别生成英语字幕。
3.2 用户单词表功能,生词可以加入单词表学习。
3.3 背单词功能。
hyperf框架 model casts 自定义类 php
<?php
namespace App\Transformers;
use Hyperf\Contract\CastsAttributes;
class AmountTransformer implements CastsAttributes
{
public function get($model, $key, $value, $attributes) :float
{
// 在这里对amount字段的值进行自定义转换
// 例如,保留两位小数
return (float) $value;
}
public function set($model, $key, $value, $attributes)
{
return $value;
}
}
实现CastsAttributes接口
调用
<?php
declare(strict_types=1);
namespace App\Model;
use App\Transformers\AmountTransformer;
class CollectionModel extends Model
{
protected ?string $table = 'collection';
protected array $casts = ["amount" => AmountTransformer::class];
}
hyperf基于jsonrpc协议微服务用apifox调用 php
{
"jsonrpc": "2.0",
"method": "calculator/add",
"params": [1, 2],
"id": 1
}
对应服务端的代码
#[RpcService(name: "CalculatorService", protocol: "jsonrpc-http", server: "jsonrpc-http",publishTo: "nacos")]
class CalculatorService implements CalculatorServiceInterface
{
// 实现一个加法方法,这里简单的认为参数都是 int 类型
public function add(int $a, int $b): int
{
$ss="22";
// 这里是服务方法的具体实现
return $a + $b;
}
}
php实现同一类型对象集合(泛型) php
java泛型
import java.util.ArrayList;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) {
// 创建一个存储Person对象的ArrayList
ArrayList<Person> personList = new ArrayList<>();
personList.add(new Person("Alice"));
personList.add(new Person("Bob"));
// 遍历Person对象ArrayList
for (Person person : personList) {
System.out.println("Person name: " + person.getName());
}
}
}
在上面的示例中,我们创建了一个存储Person对象的ArrayList。通过指定泛型类型为Person,我们可以确保ArrayList只能存储Person对象。然后我们添加两个Person对象到ArrayList中,并通过遍历ArrayList来访问存储的Person对象。
泛型的作用
泛型的作用是在编译时提供更严格的类型检查,并且在编译时捕获和消除类型转换错误。使用泛型可以使代码更加灵活和安全,因为它们允许我们在编译时指定要操作的数据类型。这样可以确保数据的类型安全性,并减少在运行时出现的类型转换错误。泛型还可以提高代码的重用性,因为可以编写可以处理多种类型的通用代码。这使得在编写集合类等数据结构时,可以更好地支持不同类型的数据。
总之,泛型的作用是提供编译时类型安全性、代码重用性和更好的类型检查。
php泛型
而php没有泛型,但我又想实现一个功能是,同一个对象的集合,这个集合只允许添加该对象。
以下是php现实,只接受AdminRulePojo类型的参数
<?php
namespace App\Http\Conllection;
use App\Http\Pojo\AdminRulePojo;
class AdminRuleConllection {
protected array $conllection=[];
public function getConllection(): array
{
return $this->conllection;
}
public function addConllection(AdminRulePojo $adminRulePojo): void
{
$this->conllection[] = $adminRulePojo;
}
}
php laravel 依赖注入,自动注入,接口绑定实现类 php
<?php
namespace App\Http\Controllers;
use App\Service\IComputerService;
use App\Validator\IValidator;
use Illuminate\Http\Request;
class IndexController extends Controller
{
private IComputerService $ComputerService;
private IValidator $Validator;
public function __construct(IComputerService $ComputerService, IValidator $Validator)
{
$this->ComputerService = $ComputerService;
$this->Validator = $Validator;
}
public function index(Request $request)
{
$param = $this->Validator->check($request);
$res = $this->ComputerService->index($param['per_page']);
return response()->json($res);
}
}
以上是一个控制器,
private IComputerService $ComputerService;
以上是业务逻辑层,限定IComputerService接口
<?php
namespace App\Service;
interface IComputerService{
public function index($per_page);
}
以上是一个IComputerService 业务逻辑层的接口
public function __construct(IComputerService $ComputerService, IValidator $Validator)
{
$this->ComputerService = $ComputerService;
$this->Validator = $Validator;
}
以上是把$ComputerService注入到IndexController
那么在哪里自动注入到服务容器呢?
<?php
namespace App\Providers;
use App\Http\Controllers\IndexController;
use App\Service\IComputerService;
use App\Service\impl\ComputerServiceImpl;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
// $this->app->bind(IComputerService::class, ComputerServiceImpl::class);
$this->app->when(IndexController::class)
->needs(IComputerService::class)
->give(ComputerServiceImpl::class);
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
//
}
}
以上代码是声明IndexController如果需要注入IComputerService接口,会自动调用ComputerServiceImpl实现类.
这样就可以实现代码解偶,符合依赖倒置原则,Dependency inversion principle,抽象不应依赖于细节,细节应依赖于抽象。
控制器如果要替换业务逻辑层即service层,不需要修改控制器的代码,只要新增和替换IComputerService 接口的实现类.
和在服务注册AppServiceProvider里修改一下 对应的实现类就可以了.
这里还有问题要注意.就是IComputerService没有指定返回数据的类型或者对象类型.这样不方便以后的修改或者替换.
rabbitmq 定时任务 指定时间发送的队列消息 php
以下是一个使用 RabbitMQ 的延迟队列来实现消息延迟发送的简单示例,使用 PHP 的 AMQP 扩展:
<?php
// 创建连接和channel
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
// 定义延迟队列和目标队列
$delayedQueueName = 'delayed_queue';
$targetQueueName = 'target_queue';
// 声明延迟队列
$channel->queue_declare($delayedQueueName, false, true, false, false, false, [
'x-dead-letter-exchange' => '',
'x-dead-letter-routing-key' => $targetQueueName
]);
// 声明目标队列
$channel->queue_declare($targetQueueName, false, true, false, false);
// 创建消息
$messageBody = 'Hello, delayed message!';
$message = new AMQPMessage($messageBody, [
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
]);
// 设置消息的 TTL 为 10 秒
$message->set('expiration', 10000);
// 发送消息到延迟队列
$channel->basic_publish($message, '', $delayedQueueName);
echo " [x] Sent 'Hello, delayed message!'\n";
// 关闭连接
$channel->close();
$connection->close();
?>
在这个示例中,我们创建了一个延迟队列 delayed_queue 和一个目标队列 target_queue。我们发送一条消息到延迟队列,并设置消息的 TTL 为 10 秒。当消息到达延迟时间后,会被投递到目标队列中。
请注意,以上示例仅为演示目的,实际应用中可能需要更多的错误处理和边界情况的考虑。
php rabbitmq 队列持久化,消息持久化 php
ubuntu停止rabbitmq
service rabbitmq-server stop
ubuntu启动rabbitmq
service rabbitmq-server start
queue队列持久化
$channel->queue_declare($queue, false, true, false, false);
durable = true 队列持久化
message消息持久化
$msg = new AMQPMessage('Hello World!'.$time, array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
重启 rabbitmq-server
queue和ready message依然存在
centos8安装多版本php,remi-php php
安装
https://itlanyan.com/install-newest-php7-and-php8-with-remi-repo/
完全卸载php
https://www.cnblogs.com/NeigeBolg/p/13395128.html
php配置位置
/etc/opt/remi/php73/
软连接 php -v
ln -s /opt/remi/php82/root/usr/bin/php /usr/bin/php
ln -s /opt/remi/php82/root/usr/bin/php-cgi /usr/bin/php-cgi
ln -s /opt/remi/php82/root/usr/bin/phar.phar /usr/bin/php.phar
启动 对应版本php-fpm
service php73-php-fpm restart
swoole的协程能否减少单个数据库语句查询的时间呢? php
问: 如果一个接口需要查询数据库并返回数据.而这个数据库查询语句需要1秒时间.那么swoole的协程能否减少请求时间呢?
答:
Swoole的协程可以帮助提高并发处理能力,但它并不能直接减少单个数据库查询的执行时间。如果你的数据库查询需要1秒钟,那么无论是否使用协程,这个查询本身的执行时间都是1秒钟。
然而,Swoole的协程可以在等待这个查询结果的同时,去执行其他的任务。例如,如果你有10个这样的查询需要执行,而且这些查询可以并行执行,那么使用Swoole的协程,理论上你可以在大约1秒钟的时间内完成所有的查询,因为这些查询是同时进行的。而如果不使用协程,你可能需要10秒钟的时间,因为每个查询都需要等待上一个查询完成后才能开始。
所以,虽然Swoole的协程不能减少单个查询的执行时间,但它可以通过并行处理来提高整体的处理能力,从而在处理多个查询时,可以显著减少总的等待时间。