PHP之hyperf学习笔记

Hyperf

Model,Dao,Service,Contronller

路由

  • 使用文件来配置路由,就是和laravel一样的
Router::addGroup([
    "middleware" => ["web", "auth"],
    "namespace" => "Hyperf\HttpServer\Controller",
    "prefix" => "hyperf",
],function (Router $router){
    Router::get("/", "Hyperf\Hyperf\Controller\IndexController@index");
});
  • 使用注解去配置路由
    #[Controller(“prefix”)]
    #[AutoController(“prefix”)]
    #[RequestMapping(path:‘index’,method:“get,post”)]
    #[GetMapping(path:“index”)]

依赖注入

  • DI依赖注入
  • IOC控制反转
  • #[Inject]
  • private UserService $user;
  • 所有的DI都是单列模式的
  • /config/dependencies.php 就是可以配置接口类和工厂类的关系
  • //接口::class => 实体类::class 这样就可以注入接口的时候就是自动转化为实体类进行注入 会去调用实体类的public function __invoke 方法
  • DI创建出来的都是单例,都是唯一的,会被所有的协程去使用

AOP

  • 被切入的类必须要是DI管理的,要使用AOP必须要切入,直接new是不行的
  • 定义一个切面 文件夹Aspect创建一个切面类 继承AbstractAspect
  • 这个是切面的函数
<?php
namespace App\Aspect;

use App\Service\SomeClass;
use App\Annotation\SomeAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;

#[Aspect]
class FooAspect extends AbstractAspect
{
    // 要切入的类或 Trait,可以多个,亦可通过 :: 标识到具体的某个方法,通过 * 可以模糊匹配
    //定义要切入的类 
    public array $classes = [
        SomeClass::class,
        'App\Service\SomeClass::someMethod',
        'App\Service\SomeClass::*Method',
    ];

    // 要切入的注解,具体切入的还是使用了这些注解的类,仅可切入类注解和类方法注解
    public array $annotations = [
        SomeAnnotation::class,
    ];

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        // 切面切入后,执行对应的方法会由此来负责
        // $proceedingJoinPoint 为连接点,通过该类的 process() 方法调用原方法并获得结果
        // 在调用前进行某些处理
        $result = $proceedingJoinPoint->process();
        // 在调用后进行某些处理
        return $result;
    }
}
  • 直接使用注解配置来达到和上面一样的目的
<?php
namespace App\Aspect;

use App\Service\SomeClass;
use App\Annotation\SomeAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;

#[
    Aspect(
        classes: [
            SomeClass::class,
            "App\Service\SomeClass::someMethod",
            "App\Service\SomeClass::*Method"
        ],
        annotations: [
            SomeAnnotation::class
        ]
    )
]
class FooAspect extends AbstractAspect
{
    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        // 切面切入后,执行对应的方法会由此来负责
        // $proceedingJoinPoint 为连接点,通过该类的 process() 方法调用原方法并获得结果
        // 在调用前进行某些处理
        $result = $proceedingJoinPoint->process();
        // 在调用后进行某些处理
        return $result;
    }
}
  • 在aspect中获取一些需要的参数 以更灵活的实现aspect
<?php
namespace App\Aspect;

use App\Service\SomeClass;
use App\Annotation\SomeAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;

#[Aspect]
class FooAspect extends AbstractAspect
{
    public array $classes = [
        SomeClass::class,
        'App\Service\SomeClass::someMethod',
        'App\Service\SomeClass::*Method',
    ];

    public array $annotations = [
        SomeAnnotation::class,
    ];

    public function process(ProceedingJoinPoint $proceedingJoinPoint)
    {
        // 获取当前方法反射原型
        /** @var \ReflectionMethod **/
        $reflect = $proceedingJoinPoint->getReflectMethod();

        // 获取调用方法时提交的参数
        $arguments = $proceedingJoinPoint->getArguments(); // array

        // 获取原类的实例并调用原类的其他方法
        $originalInstance = $proceedingJoinPoint->getInstance();
        $originalInstance->yourFunction();

        // 获取注解元数据
        /** @var \Hyperf\Di\Aop\AnnotationMetadata **/
        $metadata = $proceedingJoinPoint->getAnnotationMetadata();

        // 调用不受代理类影响的原方法
        $proceedingJoinPoint->processOriginalMethod();

        // 不执行原方法,做其他操作
        $result = date('YmdHis', time() - 86400);
        return $result;
    }
}
  • 代理类缓存 config/config.php scan_cacheable

注解

  • 没搞清楚使用在哪里 下次在来

事件机制

  • 这个有点像是队列的意思
  • 其实就是为了解耦
  • 定义一个事件 这个事件来了就是要做一些其他的操作 用户注册事件,用户注册完之后可能要做一些其他的事情,比如发送邮箱什么的
  • 定义一个事件
<?php
namespace App\Event;

class UserRegistered
{
    // 建议这里定义成 public 属性,以便监听器对该属性的直接使用,或者你提供该属性的 Getter
    public $user;
    
    public function __construct($user)
    {
        $this->user = $user;    
    }
}
  • 定义一个监听器
<?php
namespace App\Listener;

use App\Event\UserRegistered;
use Hyperf\Event\Contract\ListenerInterface;

class UserRegisteredListener implements ListenerInterface
{
    public function listen(): array
    {
        // 返回一个该监听器要监听的事件数组,可以同时监听多个事件
        return [
            UserRegistered::class,
        ];
    }

    /**
     * @param UserRegistered $event
     */
    public function process(object $event): void
    {
        // 事件触发后该监听器要执行的代码写在这里,比如该示例下的发送用户注册成功短信等
        // 直接访问 $event 的 user 属性获得事件触发时传递的参数值
        // $event->user;
        
    }
}
  • 去配置监听器 让这个监听器在监听
  • config/autoload/listeners.php
<?php
return [
    \App\Listener\UserRegisteredListener::class,
];
  • 通过注解去实现监听器
<?php
namespace App\Listener;

use App\Event\UserRegistered;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Event\Contract\ListenerInterface;

#[Listener]
class UserRegisteredListener implements ListenerInterface
{
    public function listen(): array
    {
        // 返回一个该监听器要监听的事件数组,可以同时监听多个事件
        return [
            UserRegistered::class,
        ];
    }

    /**
     * @param UserRegistered $event
     */
    public function process(object $event): void
    {
        // 事件触发后该监听器要执行的代码写在这里,比如该示例下的发送用户注册成功短信等
        // 直接访问 $event 的 user 属性获得事件触发时传递的参数值
        // $event->user;
    }
}
在通过注解注册监听器时,我们可以通过设置 priority 属性定义当前监听器的顺序,如 #[Listener(priority=1)] ,底层使用 SplPriorityQueue 结构储存,priority 数字越大优先级越高
  • 对监听器的一个使用
<?php
namespace App\Service;

use Hyperf\Di\Annotation\Inject;
use Psr\EventDispatcher\EventDispatcherInterface;
use App\Event\UserRegistered; 

class UserService
{
    #[Inject]
    private EventDispatcherInterface $eventDispatcher;
    
    public function register()
    {
        // 我们假设存在 User 这个实体
        $user = new User();
        $result = $user->save();
        // 完成账号注册的逻辑
        // 这里 dispatch(object $event) 会逐个运行监听该事件的监听器
        $this->eventDispatcher->dispatch(new UserRegistered($user));
        return $result;
    }
}

中间件

  • config/autoload/middlewares.php 全局中间件
<?php
return [
    // http 对应 config/autoload/server.php 内每个 server 的 name 属性对应的值,该配置仅应用在该 Server 中
    'http' => [
        // 数组内配置您的全局中间件,顺序根据该数组的顺序
        YourMiddleware::class
    ],
];
  • 使用注解的方式 #[Middleware(FooMiddleware::class)]
  • 多个中间件 #[Middleware([FooMiddleware::class,barMiddleware::class])]
  • 生成中间件 php ./bin/hyperf.php gen:middleware Auth/FooMiddleware
<?php

declare(strict_types=1);

namespace App\Middleware\Auth;

use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class FooMiddleware implements MiddlewareInterface
{
    protected ContainerInterface $container;

    protected RequestInterface $request;

    protected HttpResponse $response;

    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request)
    {
        $this->container = $container;
        $this->response = $response;
        $this->request = $request;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        // 根据具体业务判断逻辑走向,这里假设用户携带的token有效
        $isValidToken = true;
        if ($isValidToken) {
            return $handler->handle($request);
        }

        return $this->response->json(
            [
                'code' => -1,
                'data' => [
                    'error' => '中间件验证token无效,阻止继续向下执行',
                ],
            ]
        );
    }
}
  • 中间件的执行顺序
// 全局中间件配置文件 middleware.php
return [
    'http' => [
        YourMiddleware::class,
        YourMiddlewareB::class => 3,
    ],
];
  • 中间件的注解方式
// 注解中间件配置
#[AutoController]
#[Middleware(FooMiddleware::class)]
#[Middleware(FooMiddlewareB::class, 3)]
#[Middlewares([FooMiddlewareC::class => 1, BarMiddlewareD::class => 4])]
class IndexController
{
    
}
  • 如果要在中间件中修改$request那么需要使用功能Context去改变
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

// $request 和 $response 为修改后的对象
$request = \Hyperf\Context\Context::set(ServerRequestInterface::class, $request);
$response = \Hyperf\Context\Context::set(ResponseInterface::class, $response);
  • 默认情况下在处理路由的时候,找不到或者什么都是执行CoreMiddleware 可以重写这个方法
  • 跨域中间件 hyperf官网有

请求Request

  • 在hyperf中一般注入的都是RequestInterface
  • 常用方法的集合
$request->path();
$request->url();
$request->fullUrl();
$request->getMethod();
$request->all();
$request->input("name",'most');
// 存在则返回,不存在则返回 null
$name = $request->query('name');
// 存在则返回,不存在则返回默认值 Hyperf
$name = $request->query('name', 'Hyperf');
// 不传递参数则以关联数组的形式返回所有 Query 参数
$name = $request->query();
$request->has('name');
$request->cookie('name');
// 存在则返回一个 Hyperf\HttpMessage\Upload\UploadedFile 对象,不存在则返回 null
$file = $request->file('photo');
if ($request->hasFile('photo')) {
    // ...
}
if ($request->file('photo')->isValid()) {
    // ...
}
// 该路径为上传文件的临时路径
$path = $request->file('photo')->getPath();

// 由于 Swoole 上传文件的 tmp_name 并没有保持文件原名,所以这个方法已重写为获取原文件名的后缀名
$extension = $request->file('photo')->getExtension();
$file = $request->file('photo');
$file->moveTo('/foo/bar.jpg');

// 通过 isMoved(): bool 方法判断方法是否已移动
if ($file->isMoved()) {
    // ...
}

响应Responce

  • r e s p o n s e − > j s o n ( response->json( response>json(data);
  • r e s p o n s e − > x m l ( response->xml( response>xml(data);
  • $response->raw(‘Hello Hyperf.’);
  • 还有问价下载的方法具体看文档

控制器

  • 实现interface接口类

异常

<?php
namespace App\Exception\Handler;

use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use App\Exception\FooException;
use Throwable;
class FooExceptionHandler extends  ExceptionHandler
{
    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        // 判断被捕获到的异常是希望被捕获的异常
        if ($throwable instanceof FooException) {
            // 格式化输出
            $data = json_encode([
                'code' => $throwable->getCode(),
                'message' => $throwable->getMessage(),
            ], JSON_UNESCAPED_UNICODE);
            // 阻止异常冒泡
            $this->stopPropagation();
            return $response->withStatus(500)->withBody(new SwooleStream($data));
        }
        // 交给下一个异常处理器
        return $response;
        // 或者不做处理直接屏蔽异常
    }
    /**
     * 判断该异常处理器是否要对该异常进行处理
     */
    public function isValid(Throwable $throwable): bool
    {
        return true;
    }
}

缓存

  • SimpleCache
$cache = $container->get(\Psr\SimpleCache\CacheInterface::class);
  • 这文档缓存讲的不太行

日志

  • 就这样的吧 讲的也不太行

分页器

  • 没啥好讲的 默认是自动读取page的
  • UserModel::paginate(10)

自动化测试

  • 模拟http请求
<?php
use Hyperf\Testing\Client;
$client = make(Client::class);
$result = $client->get('/');

验证器

  • 全局验证器 在server.php 中配置
<?php
return [
    // 下面的 http 字符串对应 config/autoload/server.php 内每个 server 的 name 属性对应的值,意味着对应的中间件配置仅应用在该 Server 中
    'http' => [
        // 数组内配置您的全局中间件,顺序根据该数组的顺序
        \Hyperf\Validation\Middleware\ValidationMiddleware::class
        // 这里隐藏了其它中间件
    ],
];
  • 使用方式
  • 1.创建一个验证器
php bin/hyperf.php gen:request FooRequest
  • 2.编写规则
/**
 * 获取应用到请求的验证规则
 */
public function rules(): array
{
    return [
        'foo' => 'required|max:255',
        'bar' => 'required',
    ];
}

-3. 使用

<?php
namespace App\Controller;

use App\Request\FooRequest;

class IndexController
{
    public function index(FooRequest $request)
    {
        // 传入的请求通过验证...
        
        // 获取通过验证的数据...
        $validated = $request->validated();
    }
}

  • 可以添加一个自定义的异常类来处理这个文件
  • 验证规则要去看

数据库模型

  • 执行原生sql
<?php
use Hyperf\DbConnection\Db;
$users = Db::select('SELECT * FROM `user` WHERE gender = ?',[1]);  //  返回array 
foreach($users as $user){
    echo $user->name;
}
//执行类
<?php

use Hyperf\DbConnection\Db;

$inserted = Db::insert('INSERT INTO user (id, name) VALUES (?, ?)', [1, 'Hyperf']); // 返回是否成功 bool

$affected = Db::update('UPDATE user set name = ? WHERE id = ?', ['John', 1]); // 返回受影响的行数 int

$affected = Db::delete('DELETE FROM user WHERE id = ?', [1]); // 返回受影响的行数 int

$result = Db::statement("CALL pro_test(?, '?')", [1, 'your words']);  // 返回 bool  CALL pro_test(?,?) 为存储过程,属性为 MODIFIES SQL DATA
  • 事务
use Hyperf\DbConnection\Db;

Db::beginTransaction();
try{
    // Do something...
    Db::commit();
} catch(\Throwable $ex){
    Db::rollBack();
}
  • 打印最后一条sql
// 打印最后一条 SQL 相关数据
var_dump(Arr::last(Db::getQueryLog()));
  • 获取的多个值是Collection 获取的单个值是stdClass
  • 获取第一条 ->first()
  • 获取第一列值 ->pluck(‘name’) 也可以多个 ->p
  • 获取单个值 ->value(“id”)
  • 查询指定字段 ->select(‘id’,‘name’,‘gender’)
  • Or
$users = Db::table('user')
    ->where('gender', 1)
    ->orWhere('name', 'John')
    ->get();
  • whereBetween
$users = Db::table('users')->whereBetween('votes', [1, 100])->get();

模型

  • 创建模型 php ./bin/hyper.php gen:model table_name
  • 时间戳
<?php
declare(strict_types=1);
namespace App\Model;
use Hyperf\DbConnection\Model\Model;
class User extends Model
{
    public bool $timestamps = false;
}
  • 保护属性 f i l l a b l e 可填充, fillable 可填充, fillable可填充,guarded 保护属性
  • 配置软删除
<?php
namespace App\Model;
use Hyperf\Database\Model\Model;
use Hyperf\Database\Model\SoftDeletes;
class User extends Model
{
    use SoftDeletes;
}

模型关系

  • 一对一 User有一个Role
<?php
declare(strict_types=1);
namespace App\Models;
use Hyperf\DbConnection\Model\Model;
class User extends Model
{
    public function role()
    {
    	第一个参数 one的类,User表中的外键 主键 一对一是主表需要有外键 当然谁都可以成为主表
        return $this->hasOne(Role::class, 'user_id', 'id');
    }
}
  • 一对多 User有多个Book
<?php

declare(strict_types=1);

namespace App\Models;

use Hyperf\DbConnection\Model\Model;

class User extends Model
{
    public function books()
    {
        return $this->hasMany(Book::class, 'user_id', 'id');
    }
}
  • 一对多反向 属于关系
<?php

declare(strict_types=1);

namespace App\Models;

use Hyperf\DbConnection\Model\Model;

class Book extends Model
{
    public function author()
    {
    	//参数永远都是外键 然后主键
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
}
  • 多对多
  • 假设User表和Role
  • 前置条件 role_id user_id 中间表 role_user
<?php

namespace App;

use Hyperf\DbConnection\Model\Model;

class User extends Model
{
    public function roles()
    {
    外表,中间表,自己的的外键,外键  记住这个顺序 基本都是按这个顺序来的
    return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');

        //return $this->belongsToMany(Role::class);
    }
}
  • 获取中间表字段
$user = User::find(1);

foreach ($user->roles as $role) {
    echo $role->pivot->created_at;
}

  • 如果需要其他字段需要在关联的时候指出
return $this->belongsToMany(Role::class)->withPivot('column1', 'column2');

访问器&修改器

  • 访问器
<?php

namespace App;

use Hyperf\DbConnection\Model\Model;

class User extends Model
{
    /**
     * 获取用户的姓名.
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }
}
  • 修改器
<?php

namespace App;

use Hyperf\DbConnection\Model\Model;

class User extends Model
{
    /**
     * 设置用户的姓名.
     *
     * @param  string  $value
     * @return void
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/966150.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++小等于的所有奇数和=最大奇数除2加1的平方。

缘由 三种思路解题&#xff1a;依据算术推导得到一个规律&#xff1a;小等于的所有奇数和等于最大奇数除以2加1的平方。将在后续发布&#xff0c;总计有十种推导出来的实现代码。 int a 0,aa 1,aaa 0;cin >> a; while (aa<a) aaa aa, aa 2;cout << aaa;i…

【CPP】CPP经典面试题

文章目录 引言1. C 基础1.1 C 中的 const 关键字1.2 C 中的 static 关键字 2. 内存管理2.1 C 中的 new 和 delete2.2 内存泄漏 3. 面向对象编程3.1 继承和多态3.2 多重继承 4. 模板和泛型编程4.1 函数模板4.2 类模板 5. STL 和标准库5.1 容器5.2 迭代器 6. 高级特性6.1 移动语义…

深入浅出谈VR(虚拟现实、VR镜头)

1、VR是什么鬼&#xff1f; 近两年VR这次词火遍网上网下&#xff0c;到底什么是VR&#xff1f;VR是“Virtual Reality”&#xff0c;中文名字是虚拟现实&#xff0c;是指采用计算机技术为核心的现代高科技手段生成一种虚拟环境&#xff0c;用户借助特殊的输入/输出设备&#x…

【Redis】安装配置Redis超详细教程 / Linux版

Linux安装配置Redis超详细教程 安装redis依赖安装redis启动redis停止redisredis.conf常见配置设置redis为后台启动修改redis监听地址设置工作目录修改密码监听的端口号数据库数量设置redis最大内存设置日志文件设置redis开机自动启动 学习视频&#xff1a;黑马程序员Redis入门到…

[LeetCode]day16 242.有效的字母异位词

242. 有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的 字母异位词 示例 1: 输入: s "anagram", t "nagaram" 输出: true示例 2: 输入: s "rat"…

[MoeCTF 2022]baby_file

题目 <html> <title>Heres a secret. Can you find it?</title> <?phpif(isset($_GET[file])){$file $_GET[file];include($file); }else{highlight_file(__FILE__); } ?> </html> 读取flag /?filephp://filter/readconvert.base64-encode…

Centos挂载镜像制作本地yum源,并补装图形界面

内网环境centos7.9安装图形页面内网环境制作本地yum源 上传镜像到服务器目录 创建目录并挂载镜像 #创建目录 cd /mnt/ mkdir iso#挂载 mount -o loop ./CentOS-7-x86_64-DVD-2009.iso ./iso #前面镜像所在目录&#xff0c;后面所挂载得目录#检查 [rootlocalhost mnt]# df -h…

判断您的Mac当前使用的是Zsh还是Bash:echo $SHELL、echo $0

要判断您的Mac当前使用的是Zsh还是Bash&#xff0c;可以使用以下方法&#xff1a; 查看默认Shell: 打开“终端”应用程序&#xff0c;然后输入以下命令&#xff1a; echo $SHELL这将显示当前默认使用的Shell。例如&#xff0c;如果输出是/bin/zsh&#xff0c;则说明您使用的是Z…

python 小游戏:扫雷

目录 1. 前言 2. 准备工作 3. 生成雷区 4. 鼠标点击扫雷 5. 胜利 or 失败 6. 游戏效果展示 7. 完整代码 1. 前言 本文使用 Pygame 实现的简化版扫雷游戏。 如上图所示&#xff0c;游戏包括基本的扫雷功能&#xff1a;生成雷区、左键点击扫雷、右键标记地雷、显示数字提示…

【重新认识C语言----文件管理篇】

目录 ​编辑 -----------------------------------------begin------------------------------------- 引言 1. 文件的基本概念 2. 文件指针 3. 文件的打开与关闭 3.1 打开文件 3.2 关闭文件 4. 文件的读写操作 4.1 读取文件 4.1.1 使用fgetc()读取文件 4.1.2 使用fg…

EasyExcel 导出合并层级单元格

EasyExcel 导出合并层级单元格 一、案例 案例一 1.相同订单号单元格进行合并 合并结果 案例二 1.相同订单号的单元格进行合并2.相同订单号的总数和总金额进行合并 合并结果 案例三 1.相同订单号的单元格进行合并2.相同订单号的商品分类进行合并3.相同订单号的总数和总金额…

WPF 进度条(ProgressBar)示例一

本文讲述&#xff1a;WPF 进度条(ProgressBar)简单的样式修改和使用。 进度显示界面&#xff1a;使用UserControl把ProgressBar和进度值以及要显示的内容全部组装在UserControl界面中&#xff0c;方便其他界面直接进行使用。 <UserControl x:Class"DefProcessBarDemo…

LabVIEW自定义测量参数怎么设置?

以下通过一个温度采集案例&#xff0c;说明在 LabVIEW 中设置自定义测量参数的具体方法&#xff1a; 案例背景 ​ 假设使用 NI USB-6009 数据采集卡 和 热电偶传感器 监测温度&#xff0c;需自定义以下参数&#xff1a; 采样率&#xff1a;1 kHz 输入量程&#xff1a;0~10 V&a…

新能源产业的质量革命:六西格玛培训如何重塑制造竞争力

在新能源行业狂飙突进的今天&#xff0c;企业若想在全球供应链中占据高地&#xff0c;仅靠技术突破已远远不够。制造效率的毫厘之差&#xff0c;可能成为市场话语权的千里之距。某光伏巨头曾因电池片良率低于行业均值1.5%&#xff0c;导致年损失超2.3亿元——这恰恰印证了六西格…

(11)gdb 笔记(4):设置执行方向 set exec-direction,

&#xff08;28&#xff09;引入 record 后&#xff0c;可以 设置执行方向 set exec-direction &#xff1a; 实践&#xff1a; &#xff08;29&#xff09; &#xff08;33&#xff09; 谢谢

redis持久化理论

0 前言 什么是持久化 redis操作都是在内存中&#xff0c;如果出现宕机的话&#xff0c;数据将不复存在&#xff0c;所以持久化是将内存中的数据刷盘到磁盘中&#xff0c;redis可以提供RDB和AOF将数据写入磁盘中。 一 持久化技术 本章节将介绍持久化RDB和AOF两个技术&#xf…

25/2/7 <机器人基础>雅可比矩阵计算 雅可比伪逆

雅可比矩阵计算 雅可比矩阵的定义 假设我们有一个简单的两个关节的平面机器人臂&#xff0c;其末端执行器的位置可以表示为&#xff1a; 其中&#xff1a; L1​ 和 L2 是机器人臂的长度。θ1​ 和 θ2是关节的角度。 计算雅可比矩阵 雅可比矩阵 JJ 的定义是将关节速度与末…

鸿蒙UI(ArkUI-方舟UI框架)- 使用文本

返回主章节 → 鸿蒙UI&#xff08;ArkUI-方舟UI框架&#xff09; 文本使用 文本显示 (Text/Span) Text是文本组件&#xff0c;通常用于展示用户视图&#xff0c;如显示文章的文字内容。Span则用于呈现显示行内文本。 创建文本 string字符串 Text("我是一段文本"…

科技赋能数字内容体验的核心技术探索

内容概要 在数字化时代&#xff0c;科技的迅猛发展为我们的生活和工作带来了深刻的变革。数字内容体验已经成为人们获取信息和娱乐的重要途径&#xff0c;而这背后的技术支持则扮演着至关重要的角色。尤其是在人工智能、虚拟现实和区块链等新兴技术的推动下&#xff0c;数字内…

详细教程 | 如何使用DolphinScheduler调度Flink实时任务

Apache DolphinScheduler 非常适用于实时数据处理场景&#xff0c;尤其是与 Apache Flink 的集成。DolphinScheduler 提供了丰富的功能&#xff0c;包括任务依赖管理、动态调度、实时监控和日志管理&#xff0c;能够有效简化 Flink 实时任务的管理和部署。通过 DolphinSchedule…