hyperf 二十八 修改器 一
教程:Hyperf
一 修改器和访问器
根据教程,可设置相关函数,如set属性名Attribute()、get属性名Attribute(),设置和获取属性。这在thinkphp中也常见。
修改器:set属性名Attribute();访问器:get属性名Attribute()。
1.1 原理
模型的父类Hyperf\Database\Model\Model,定义__set()、_get()、__isset()、__unset()函数。
设置属性调用__set(),获取属性调用_get()。
__set()调用set属性名Attribute(),和格式化数据。先通过set属性名Attribute()获取值,再判断是否为日期格式化日期数据。若设置字段类型,会根据设定的字段类型匹配对应的类,返回对应类。会判断是否为json数据返回json格式字符换。若调用的对应字符串含有“->”,则将该对应类对象格式化为json字符串返回。
1.2 测试
#App\Controller\Test
public function testmodifier() {$result = Article::query()->find(2)->toArray();var_dump($result);$article = Article::firstOrCreate(['title' => 'test4'],['user_id' => 2]);$result = Article::query()->where(['title' => '&test4'])->first()->toArray();var_dump($result);}
#App1\Model\Article
class Article extends Model implements CacheableInterface {use Cacheable;use SoftDeletes;/*** The table associated with the model.** @var string*/protected $table = 'articles';/*** The attributes that are mass assignable.** @var array*/protected $fillable = ['title', 'user_id']; //允许批量赋值/*** The attributes that should be cast to native types.** @var array*/protected $casts = ['id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime'];public function setTitleAttribute($value) {$this->attributes['title'] = "&" . $value;}public function getTitleAttribute($value) {return "标题:" . $value;}
}
测试结果
array(7) {["id"]=>int(2)["user_id"]=>int(1)["title"]=>string(14) "标题:test2"["created_at"]=>string(19) "2024-01-13 10:06:04"["updated_at"]=>string(19) "2024-01-13 10:06:06"["deleted_at"]=>NULL["pv_num"]=>int(0)
}array(7) {["id"]=>int(10)["user_id"]=>int(2)["title"]=>string(15) "标题:&test4"["created_at"]=>string(19) "2024-03-19 08:07:24"["updated_at"]=>string(19) "2024-03-19 08:07:24"["deleted_at"]=>NULL["pv_num"]=>int(0)
}

数据保存使用Hyperf\Database\Model\Builder::firstOrCreate()。firstOrNew()仅在对象中增加数据,未保存进数据库,这是和firstOrCreate()的区别。
过程中创建Hyperf\Database\Model\Model类对象是__construct(),会调用Model::fill()。Model::fill()使用Model::isFillable()调用Model::fillable属性,结果为true,才能设置属性,否则报错。
因为在Article::setTitleAttribute()对传入的属性增加数据。根据测试代码,查询的使用也应该加上“&”。
也是因为使用Builder::firstOrCreate()和Article::setTitleAttribute()修改传入属性,设置查询数据时不会查询到相应数据,因为查询值有差异。
tp中也遇到过相似情况。解决方法,对查询条件中数据也进行数据的换装,保证修改方式和保存之前的数据方式一样。
1.3 源码
#App1\Model\Article use Hyperf\DbConnection\Model\Model;class Article extends Model implements CacheableInterface {use Cacheable;use SoftDeletes;
}#Hyperf\DbConnection\Model\Modeluse Hyperf\Database\Model\Model as BaseModel;class Model extends BaseModel
{use HasContainer;use HasRepository;
}
#Hyperf\Database\Model\Modelabstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable,
CompressInterface {use Concerns\HasAttributes;use Concerns\HasEvents;use Concerns\HasGlobalScopes;use Concerns\HasRelationships;use Concerns\HasTimestamps;use Concerns\HidesAttributes;use Concerns\GuardsAttributes;/*** Dynamically retrieve attributes on the model.** @param string $key*/public function __get($key) {return $this->getAttribute($key);}/*** Dynamically set attributes on the model.** @param string $key* @param mixed $value*/public function __set($key, $value) {$this->setAttribute($key, $value);}/*** Determine if an attribute or relation exists on the model.** @param string $key* @return bool*/public function __isset($key) {return $this->offsetExists($key);}/*** Unset an attribute on the model.** @param string $key*/public function __unset($key) {$this->offsetUnset($key);}}
# Hyperf\Database\Model\Concerns\HasAttributes/*** Set a given attribute on the model.** @param string $key* @param mixed $value*/public function setAttribute($key, $value){// First we will check for the presence of a mutator for the set operation// which simply lets the developers tweak the attribute as it is set on// the model, such as "json_encoding" an listing of data for storage.if ($this->hasSetMutator($key)) {return $this->setMutatedAttributeValue($key, $value);}// If an attribute is listed as a "date", we'll convert it from a DateTime// instance into a form proper for storage on the database tables using// the connection grammar's date format. We will auto set the values.if ($value && $this->isDateAttribute($key)) {$value = $this->fromDateTime($value);}if ($this->isClassCastable($key)) {$this->setClassCastableAttribute($key, $value);return $this;}if ($this->isJsonCastable($key) && !is_null($value)) {$value = $this->castAttributeAsJson($key, $value);}// If this attribute contains a JSON ->, we'll set the proper value in the// attribute's underlying array. This takes care of properly nesting an// attribute in the array's value in the case of deeply nested items.if (Str::contains($key, '->')) {return $this->fillJsonAttribute($key, $value);}$this->attributes[$key] = $value;return $this;}/*** Set the value of an attribute using its mutator.** @param string $key* @param mixed $value*/protected function setMutatedAttributeValue($key, $value){return $this->{'set' . Str::studly($key) . 'Attribute'}($value);}/*** Convert a DateTime to a storable string.** @param mixed $value* @return null|string*/public function fromDateTime($value){return empty($value) ? $value : $this->asDateTime($value)->format($this->getDateFormat());}/*** Get the format for database stored dates.** @return string*/public function getDateFormat(){return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();}
/*** Set the value of a class castable attribute.** @param string $key* @param mixed $value*/protected function setClassCastableAttribute($key, $value){$caster = $this->resolveCasterClass($key);if (is_null($value)) {$this->attributes = array_merge($this->attributes, array_map(function () {},$this->normalizeCastClassResponse($key, $caster->set($this,$key,$this->{$key},$this->attributes))));} else {$this->attributes = array_merge($this->attributes,$this->normalizeCastClassResponse($key, $caster->set($this,$key,$value,$this->attributes)));}if ($caster instanceof CastsInboundAttributes || !is_object($value)) {unset($this->classCastCache[$key]);} else {$this->classCastCache[$key] = $value;}}/*** Cast the given attribute to JSON.** @param string $key* @param mixed $value* @return string*/protected function castAttributeAsJson($key, $value){$value = $this->asJson($value);if ($value === false) {throw JsonEncodingException::forAttribute($this,$key,json_last_error_msg());}return $value;}/*** Set a given JSON attribute on the model.** @param string $key* @param mixed $value* @return $this*/public function fillJsonAttribute($key, $value){[$key, $path] = explode('->', $key, 2);$this->attributes[$key] = $this->asJson($this->getArrayAttributeWithValue($path,$key,$value));return $this;}
二 日期转化及时间格式化
模型会将 created_at 和 updated_at 字段转换为 Carbon\Carbon 实例,它继承了 PHP 原生的 DateTime 类并提供了各种有用的方法。可以通过设置模型的 $dates 属性来添加其他日期属性。
2.1 原理
调用Model::_get()、Model::_set()时,会判断字段类型,为日期则转换为Carbon\Carbon类对象。可以设置日期格式。
$date为日期类型字段,$dateFormat为日期格式字符串,都在Hyperf\Database\Model\Concerns\HasAttributes中设置,也是由其转换数据类型。
HasAttributes::castAttribute()处理各种字段类型,HasAttributes::asDate()执行日期类型转换,HasAttributes::getDateFormat()获取日期格式。
日期类型默认包括created_at 、updated_at。日期默认格式"Y-m-d H:i:s"。
2.2 测试
#App1\Model\Article protected $dateFormat = 'Y-m-d H:i';public function setTitleAttribute($value) {$this->attributes['title'] = $value;}public function getTitleAttribute($value) {return $value;}
#App\Controller\TestController
public function testmodifier() {$article = Article::firstOrCreate(['title' => 'test4'],['user_id' => 2]);var_dump($article->toArray());}
测试结果
array(7) {["id"]=>int(11)["user_id"]=>int(2)["title"]=>string(5) "test4"["created_at"]=>string(16) "2024-03-22 09:04"["updated_at"]=>string(16) "2024-03-22 09:04"["deleted_at"]=>NULL["pv_num"]=>int(0)
}

测试可见 数据库中时间格式还是h:i:s,仅获取的时候是h:i格式。
Model::CREATED_AT、Model::UPDATED_AT使用Carbon::now()获取时间,并没有使用$dateFormat属性。
2.3 源码
#Hyperf\Database\Model\Model
public function __get($key) {return $this->getAttribute($key);}
public function __set($key, $value) {$this->setAttribute($key, $value);}/*** 新增时使用** @param \Hyperf\Database\Model\Builder $query* @return bool*/protected function performInsert(Builder $query) {if ($event = $this->fireModelEvent('creating')) {if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {return false;}}// First we'll need to create a fresh query instance and touch the creation and// update timestamps on this model, which are maintained by us for developer// convenience. After, we will just continue saving these model instances.if ($this->usesTimestamps()) {$this->updateTimestamps();}// If the model has an incrementing key, we can use the "insertGetId" method on// the query builder, which will give us back the final inserted ID for this// table from the database. Not all tables have to be incrementing though.$attributes = $this->getAttributes();if ($this->getIncrementing()) {$this->insertAndSetId($query, $attributes);}// If the table isn't incrementing we'll simply insert these attributes as they// are. These attribute arrays must contain an "id" column previously placed// there by the developer as the manually determined key for these models.else {if (empty($attributes)) {return true;}$query->insert($attributes);}// We will go ahead and set the exists property to true, so that it is set when// the created event is fired, just in case the developer tries to update it// during the event. This will allow them to do so and run an update here.$this->exists = true;$this->wasRecentlyCreated = true;$this->fireModelEvent('created');return true;}
/*** 修改时使用** @param \Hyperf\Database\Model\Builder $query* @return bool*/protected function performUpdate(Builder $query) {// If the updating event returns false, we will cancel the update operation so// developers can hook Validation systems into their models and cancel this// operation if the model does not pass validation. Otherwise, we update.if ($event = $this->fireModelEvent('updating')) {if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {return false;}}// First we need to create a fresh query instance and touch the creation and// update timestamp on the model which are maintained by us for developer// convenience. Then we will just continue saving the model instances.if ($this->usesTimestamps()) {$this->updateTimestamps();}// Once we have run the update operation, we will fire the "updated" event for// this model instance. This will allow developers to hook into these after// models are updated, giving them a chance to do any special processing.$dirty = $this->getDirty();if (count($dirty) > 0) {$this->setKeysForSaveQuery($query)->update($dirty);$this->syncChanges();$this->fireModelEvent('updated');}return true;}public function save(array $options = []): bool {$this->mergeAttributesFromClassCasts();$query = $this->newModelQuery();// If the "saving" event returns false we'll bail out of the save and return// false, indicating that the save failed. This provides a chance for any// listeners to cancel save operations if validations fail or whatever.if ($saving = $this->fireModelEvent('saving')) {if ($saving instanceof StoppableEventInterface && $saving->isPropagationStopped()) {return false;}}// If the model already exists in the database we can just update our record// that is already in this database using the current IDs in this "where"// clause to only update this model. Otherwise, we'll just insert them.if ($this->exists) {$saved = $this->isDirty() ? $this->performUpdate($query) : true;} else {// If the model is brand new, we'll insert it into our database and set the// ID attribute on the model to the value of the newly inserted row's ID// which is typically an auto-increment value managed by the database.$saved = $this->performInsert($query);if (!$this->getConnectionName() && $connection = $query->getConnection()) {$this->setConnection($connection->getName());}}// If the model is successfully saved, we need to do a few more things once// that is done. We will call the "saved" method here to run any actions// we need to happen after a model gets successfully saved right here.if ($saved) {$this->finishSave($options);}return $saved;}
#Hyperf\Database\Model\Concerns\HasAttributes/*** Set a given attribute on the model.** @param string $key* @param mixed $value*/
public function setAttribute($key, $value){// First we will check for the presence of a mutator for the set operation// which simply lets the developers tweak the attribute as it is set on// the model, such as "json_encoding" an listing of data for storage.if ($this->hasSetMutator($key)) {return $this->setMutatedAttributeValue($key, $value);}// If an attribute is listed as a "date", we'll convert it from a DateTime// instance into a form proper for storage on the database tables using// the connection grammar's date format. We will auto set the values.if ($value && $this->isDateAttribute($key)) {$value = $this->fromDateTime($value);}if ($this->isClassCastable($key)) {$this->setClassCastableAttribute($key, $value);return $this;}if ($this->isJsonCastable($key) && !is_null($value)) {$value = $this->castAttributeAsJson($key, $value);}// If this attribute contains a JSON ->, we'll set the proper value in the// attribute's underlying array. This takes care of properly nesting an// attribute in the array's value in the case of deeply nested items.if (Str::contains($key, '->')) {return $this->fillJsonAttribute($key, $value);}$this->attributes[$key] = $value;return $this;}public function fromDateTime($value){return empty($value) ? $value : $this->asDateTime($value)->format($this->getDateFormat());}
/*** Get an attribute from the model.** @param string $key*/public function getAttribute($key){if (!$key) {return;}// If the attribute exists in the attribute array or has a "get" mutator we will// get the attribute's value. Otherwise, we will proceed as if the developers// are asking for a relationship's value. This covers both types of values.if (array_key_exists($key, $this->getAttributes())|| $this->hasGetMutator($key)|| $this->isClassCastable($key)) {return $this->getAttributeValue($key);}// Here we will determine if the model base class itself contains this given key// since we don't want to treat any of those methods as relationships because// they are all intended as helper methods and none of these are relations.if (method_exists(self::class, $key)) {return;}return $this->getRelationValue($key);}
public function getAttributeValue($key){return $this->transformModelValue($key, $this->getAttributeFromArray($key));}protected function transformModelValue($key, $value){// If the attribute has a get mutator, we will call that then return what// it returns as the value, which is useful for transforming values on// retrieval from the model to a form that is more useful for usage.if ($this->hasGetMutator($key)) {return $this->mutateAttribute($key, $value);}// If the attribute exists within the cast array, we will convert it to// an appropriate native PHP type dependent upon the associated value// given with the key in the pair. Dayle made this comment line up.if ($this->hasCast($key)) {return $this->castAttribute($key, $value);}// If the attribute is listed as a date, we will convert it to a DateTime// instance on retrieval, which makes it quite convenient to work with// date fields without having to create a mutator for each property.if ($value !== null&& \in_array($key, $this->getDates(), false)) {return $this->asDateTime($value);}return $value;}protected function castAttribute($key, $value){$castType = $this->getCastType($key);if (is_null($value) && in_array($castType, static::$primitiveCastTypes)) {return $value;}switch ($castType) {case 'int':case 'integer':return (int) $value;case 'real':case 'float':case 'double':return $this->fromFloat($value);case 'decimal':return $this->asDecimal($value, explode(':', $this->getCasts()[$key], 2)[1]);case 'string':return (string) $value;case 'bool':case 'boolean':return (bool) $value;case 'object':return $this->fromJson($value, true);case 'array':case 'json':return $this->fromJson($value);case 'collection':return new BaseCollection($this->fromJson($value));case 'date':return $this->asDate($value);case 'datetime':case 'custom_datetime':return $this->asDateTime($value);case 'timestamp':return $this->asTimestamp($value);}if ($this->isClassCastable($key)) {return $this->getClassCastableAttributeValue($key, $value);}return $value;}
protected function asDate($value){return $this->asDateTime($value)->startOfDay();}
protected function asDateTime($value){// If this value is already a Carbon instance, we shall just return it as is.// This prevents us having to re-instantiate a Carbon instance when we know// it already is one, which wouldn't be fulfilled by the DateTime check.if ($value instanceof Carbon || $value instanceof CarbonInterface) {return Carbon::instance($value);}// If the value is already a DateTime instance, we will just skip the rest of// these checks since they will be a waste of time, and hinder performance// when checking the field. We will just return the DateTime right away.if ($value instanceof DateTimeInterface) {return Carbon::parse($value->format('Y-m-d H:i:s.u'),$value->getTimezone());}// If this value is an integer, we will assume it is a UNIX timestamp's value// and format a Carbon object from this timestamp. This allows flexibility// when defining your date fields as they might be UNIX timestamps here.if (is_numeric($value)) {return Carbon::createFromTimestamp($value);}// If the value is in simply year, month, day format, we will instantiate the// Carbon instances from that format. Again, this provides for simple date// fields on the database, while still supporting Carbonized conversion.if ($this->isStandardDateFormat($value)) {return Carbon::instance(Carbon::createFromFormat('Y-m-d', $value)->startOfDay());}$format = $this->getDateFormat();// Finally, we will just assume this date is in the format used by default on// the database connection and use that format to create the Carbon object// that is returned back out to the developers after we convert it here.if (Carbon::hasFormat($value, $format)) {return Carbon::createFromFormat($format, $value);}return Carbon::parse($value);}
public function getDateFormat(){return $this->dateFormat ?: $this->getConnection()->getQueryGrammar()->getDateFormat();}
#Hyperf\Database\Grammar
public function getDateFormat(){return 'Y-m-d H:i:s';}
#Hyperf\Database\Model\Concerns\HasTimestamps
protected function updateTimestamps(){$time = $this->freshTimestamp();if (! is_null(static::UPDATED_AT) && ! $this->isDirty(static::UPDATED_AT)) {$this->setUpdatedAt($time);}if (! $this->exists && ! is_null(static::CREATED_AT)&& ! $this->isDirty(static::CREATED_AT)) {$this->setCreatedAt($time);}}
public function setCreatedAt($value){$this->{static::CREATED_AT} = $value;return $this;}public function setUpdatedAt($value){$this->{static::UPDATED_AT} = $value;return $this;}
public function freshTimestamp(){return Carbon::now();}
#Carbon\Traits\Creator
public function __construct($time = null, $tz = null){if ($time instanceof DateTimeInterface) {$time = $this->constructTimezoneFromDateTime($time, $tz)->format('Y-m-d H:i:s.u');}if (is_numeric($time) && (!\is_string($time) || !preg_match('/^\d{1,14}$/', $time))) {$time = static::createFromTimestampUTC($time)->format('Y-m-d\TH:i:s.uP');}// If the class has a test now set and we are trying to create a now()// instance then override as required$isNow = empty($time) || $time === 'now';if (method_exists(static::class, 'hasTestNow') &&method_exists(static::class, 'getTestNow') &&static::hasTestNow() &&($isNow || static::hasRelativeKeywords($time))) {static::mockConstructorParameters($time, $tz);}// Work-around for PHP bug https://bugs.php.net/bug.php?id=67127if (!str_contains((string) .1, '.')) {$locale = setlocale(LC_NUMERIC, '0'); // @codeCoverageIgnoresetlocale(LC_NUMERIC, 'C'); // @codeCoverageIgnore}try {parent::__construct($time ?: 'now', static::safeCreateDateTimeZone($tz) ?: null);} catch (Exception $exception) {throw new InvalidFormatException($exception->getMessage(), 0, $exception);}$this->constructedObjectId = spl_object_hash($this);if (isset($locale)) {setlocale(LC_NUMERIC, $locale); // @codeCoverageIgnore}self::setLastErrors(parent::getLastErrors());}public static function now($tz = null){return new static(null, $tz);}
相关文章:
hyperf 二十八 修改器 一
教程:Hyperf 一 修改器和访问器 根据教程,可设置相关函数,如set属性名Attribute()、get属性名Attribute(),设置和获取属性。这在thinkphp中也常见。 修改器:set属性名Attribute();访问器:get属性名Attri…...
ubuntu20.04安裝輸入法
文章目录 前言一、操作過程1、安装fcitx-googlepinyin2、配置language support 前言 參考文獻 一、操作過程 1、安装fcitx-googlepinyin sudo apt-get install fcitx-googlepinyin2、配置language support 第一次點擊進去,會讓你安裝 點擊ctrl和空格切換中英文…...
2024年【熔化焊接与热切割】考试报名及熔化焊接与热切割找解析
题库来源:安全生产模拟考试一点通公众号小程序 熔化焊接与热切割考试报名考前必练!安全生产模拟考试一点通每个月更新熔化焊接与热切割找解析题目及答案!多做几遍,其实通过熔化焊接与热切割实操考试视频很简单。 1、【单选题】 下…...
聚类分析|基于层次的聚类方法及其Python实现
聚类分析|基于层次的聚类方法及其Python实现 0. 基于层次的聚类方法1. 簇间距离度量方法1.1 最小距离1.2 最大距离1.3 平均距离1.4 中心法1.5 离差平方和 2. 基于层次的聚类算法2.1 凝聚(Agglomerative)2.3 分裂(Divisive) 3. 基于…...
前端实现导出xlsx功能
1.安装xlsx插件 npm install xlsx 2.示例 import XLSX from xlsx;// 示例数据 const data [[Name, Age, Country],[Alice, 25, USA],[Bob, 30, Canada],[Charlie, 28, UK] ];// 创建一个 Workbook 对象 const wb XLSX.utils.book_new(); const ws XLSX.utils.aoa_to_sheet…...
算法系列--动态规划--⼦数组、⼦串系列(数组中连续的⼀段)(1)
💕"我们好像在池塘的水底,从一个月亮走向另一个月亮。"💕 作者:Mylvzi 文章主要内容:算法系列–动态规划–⼦数组、⼦串系列(数组中连续的⼀段)(1) 大家好,今天为大家带来的是算法系…...
RESTful架构
RESTful架构中的URI设计与传统的URL设计有一些区别。让我通过具体的例子来解释一下: 传统的URL设计通常将操作和资源混合在一起,例如: 获取所有图书:GET /getBooks获取特定图书:GET /getBookById/{id}创建新图书&…...
从IO操作与多线程的思考到Redis-6.0
IO操作->线程阻塞->释放CPU资源->多线程技术提升CPU利用率 在没有涉及磁盘操作和网络请求的程序中,通常不会出现线程等待状态。线程等待状态通常是由于线程需要等待某些事件的发生,比如I/O操作完成、网络请求返回等。如果程序只是进行计算或者简…...
MNN介绍、安装和编译
MNN是一个轻量级的深度学习推理框架,由阿里巴巴公司开发。它支持多种硬件平台,包括CPU、GPU和NPU,并提供高效、高性能的深度学习模型推理服务。下面是MNN的安装和编译步骤: 下载MNN源代码 在MNN的GitHub页面(https://g…...
【计算机图形学】AO-Grasp: Articulated Object Grasp Generation
对AO-Grasp: Articulated Object Grasp Generation的简单理解 文章目录 1. 做的事情2. AO-Grasp数据集2.1 抓取参数化和label标准2.2 语义和几何感知的抓取采样 3. AO-Grasp抓取预测3.1 预测抓取点3.2 抓取方向预测 4. 总结 1. 做的事情 引入AO-Grasp,grasp propo…...
「媒体宣传」财经类媒体邀约资源有哪些?-51媒体
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 财经类媒体邀约资源包括但不限于以下几类: 商业杂志和报纸:可以邀请如《财经》、《新财富》、《经济观察报》等主流商业杂志和报纸。这些媒体通常具有较强的品牌影…...
学习资料记录
http://interview.wzcu.com/Golang/%E4%BB%A3%E7%A0%81%E8%80%83%E9%A2%98.html map底层 https://zhuanlan.zhihu.com/p/616979764 go修养 https://www.yuque.com/aceld/golang/ga6pb1#4b19dba5 https://golang.dbwu.tech/performance/map_pre_alloc/ https://juejin.cn/pos…...
数据结构进阶篇 之 【二叉树】详细概念讲解(带你认识何为二叉树及其性质)
有朋自远方来,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,鞭数十,驱之别院 一、二叉树 1、二叉树的概念 1.1 二叉树中组分构成名词概念 1.2 二叉树的结构概念 1.3 特殊的二叉树 2、二叉树的存储结构 …...
vue.js制作学习计划表案例
通俗易懂,完成“学习计划表”用于对学习计划进行管理,包括对学习计划进行添加、删除、修改等操作。 一. 初始页面效果展示 二.添加学习计划页面效果展示 三.修改学习计划完成状态的页面效果展示 四.删除学习计划 当学习计划处于“已完成”状态时&…...
nginx localtion 匹配规则
1、语法规则 语法规则:location[|~|^~*|^~]/uri/{… } 表示精确匹配,这个优先级也是最高的 ^~ 表示 uri 以某个常规字符串开头,理解为匹配 url 路径即可。 nginx 不对 url 做编码,因此请求为 /image/20%/aa,可以被规则^~ /imag…...
Git:分布式版本控制系统
目录 Git的特点和功能常见的功能和对应的命令 Git的特点和功能 Git是一个分布式版本控制系统,用于跟踪和管理项目的代码变更。它是由Linus Torvalds在2005年创建的,旨在管理Linux内核的开发。Git具有以下特点和功能: 分布式版本控制…...
[STL]priority_queue类及反向迭代器的模拟实现
🪐🪐🪐欢迎来到程序员餐厅💫💫💫 今日主菜: priority_queue类及反向迭代器 主厨:邪王真眼 主厨的主页:Chef‘s blog 所属专栏:c大冒险 向着c&…...
vue2 脚手架
安装 文档:https://cli.vuejs.org/zh/ 第一步:全局安装(仅第一次执行) npm install -g vue/cli 或 yarn global add vue/cli 备注:如果出现下载缓慢:请配置npm 淘宝镜像: npm config set regis…...
【OpenStack】OpenStack实战之开篇
目录 那么,OpenStack是什么?云又是什么?关于容器应用程序OpenStack如何适配其中?如何设置它?如何学会使用它?推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战我的整个职业生涯到目前为止一直围绕着为离线或隔离网络设计和开发应用程…...
Python实现WebSocket通信
WebSocket是一种在单个TCP连接上进行全双工通信的协议,位于 OSI 模型的应用层。 与传统的HTTP请求-响应模型不同,WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,实现实时性和互动性…...
3分钟搞定Windows桌面整理:NoFences免费开源工具终极指南
3分钟搞定Windows桌面整理:NoFences免费开源工具终极指南 【免费下载链接】NoFences 🚧 Open Source Stardock Fences alternative 项目地址: https://gitcode.com/gh_mirrors/no/NoFences 你是否每天都要在杂乱的Windows桌面上寻找文件ÿ…...
小模型爆发出惊人能量!斯坦福开源框架AgentFlow如何实现复杂任务中的可靠工具使用?
本文介绍了斯坦福大学开源的模块化智能体框架AgentFlow,它通过独特的架构设计和训练方法,在工具集成和规划能力上取得了突破性进展。AgentFlow以Qwen-2.5-7B-Instruct为基础,在10个基准测试中表现突出,超越了大50倍的模型和GPT-4o…...
通过curl命令调试Taotoken大模型API,快速排查接入问题
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过curl命令调试Taotoken大模型API,快速排查接入问题 在接入大模型服务时,直接使用HTTP请求进行调试是一种…...
SQL 数据库从免费到付费选型实战:支撑真实规模产品的能力分析与选择指南
引言:为什么 SQL 数据库选型如此重要? 在当今数据驱动的时代,数据库是任何数字产品的核心基础设施。无论是初创公司的 MVP(最小可行产品),还是日活百万的成熟应用,数据库的选择直接影响着产品的性能、成本、可扩展性和开发效率。 对于技术决策者而言,面对琳琅满目的 …...
微信抓包全链路实战:Proxifier+Fiddler+Burp协同排障指南
1. 为什么微信抓包成了“玄学”,而你总在重装系统? 微信抓包这件事,我干了七年,从2017年用Charles配iOS证书开始,到今天手头常备三套环境:Mac上跑Fiddler EverywhereProxifier组合应对企业微信定制版&…...
解决Claude Code密钥被封与Token不足的替代接入方案
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 解决Claude Code密钥被封与Token不足的替代接入方案 对于频繁使用Claude Code编程助手的开发者而言,开发流程中突然遇到…...
一键搞定B站视频下载:跨平台工具BilibiliDown完整使用指南
一键搞定B站视频下载:跨平台工具BilibiliDown完整使用指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirro…...
终极游戏库管理器Playnite:一站式管理20+平台游戏的最佳解决方案
终极游戏库管理器Playnite:一站式管理20平台游戏的最佳解决方案 【免费下载链接】Playnite Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games. 项目…...
基因鉴定步骤及常见问题
一、基因组 DNA 提取(一)消化鼠尾消化液配方为溶剂水与SDS、酶。Solution:0.5%SDS破坏细胞膜和核膜,释放DNA。Enzyme:1 mg/ml蛋白酶K分解样本中的蛋白质,释放DNA。(二)样品处理1、小…...
基于RK平台的智慧出行方案:从芯片选型到车规级开发的实战指南
1. 项目概述:当“智慧出行”遇上“RK平台”最近几年,如果你关注汽车电子或者物联网领域,一定对“智慧出行”这个词不陌生。它早已不是科幻电影里的概念,而是真真切切地走进了我们的生活,从智能座舱里流畅的语音交互、多…...
