From e4c6df7c7e916cef9f35d45a110fb74b29f77201 Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 16:16:59 +0800 Subject: [PATCH 1/9] =?UTF-8?q?perf:=20=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=8C=E4=BD=BF=E7=94=A8=20`$array[]=3D=20...;`=20?= =?UTF-8?q?=E6=9B=BF=E4=BB=A3=20`array=5Fpush(...)`=20=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=EF=BC=8C=E6=80=A7=E8=83=BD=E6=8F=90=E5=8D=87=202=20=20?= =?UTF-8?q?=E5=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > [EA] '$this->appends[] = $action' here would be up to 2x faster. --- src/Console/ActionCommand.php | 4 ++-- src/Grid/Column/HasDisplayers.php | 2 +- src/Grid/Displayers/Actions.php | 4 ++-- src/Grid/Displayers/DropdownActions.php | 2 +- src/Grid/Displayers/Limit.php | 2 +- src/Grid/Tools/Selector.php | 2 +- src/Http/Controllers/PermissionController.php | 2 +- src/Show/Field.php | 2 +- src/Tree/Actions.php | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Console/ActionCommand.php b/src/Console/ActionCommand.php index 9d41fcac8..5f0860057 100644 --- a/src/Console/ActionCommand.php +++ b/src/Console/ActionCommand.php @@ -131,10 +131,10 @@ protected function getDefaultNamespace($rootNamespace) $segments = explode('\\', config('admin.route.namespace')); array_pop($segments); - array_push($segments, 'Actions'); + $segments[] = 'Actions'; if (isset($this->namespaceMap[$this->choice])) { - array_push($segments, $this->namespaceMap[$this->choice]); + $segments[] = $this->namespaceMap[$this->choice]; } return implode('\\', $segments); diff --git a/src/Grid/Column/HasDisplayers.php b/src/Grid/Column/HasDisplayers.php index 5b49d77b3..d0a471aea 100644 --- a/src/Grid/Column/HasDisplayers.php +++ b/src/Grid/Column/HasDisplayers.php @@ -167,7 +167,7 @@ public function append($val) } if (is_array($v)) { - array_push($v, $val); + $v[] = $val; return $v; } elseif ($v instanceof Collection) { diff --git a/src/Grid/Displayers/Actions.php b/src/Grid/Displayers/Actions.php index 0773f91f2..8690b5346 100755 --- a/src/Grid/Displayers/Actions.php +++ b/src/Grid/Displayers/Actions.php @@ -54,7 +54,7 @@ public function append($action) { $this->prepareAction($action); - array_push($this->appends, $action); + $this->appends[] = $action; return $this; } @@ -229,7 +229,7 @@ public function display(array $callbacks = []) foreach ($this->actions as $action => $enable) { if ($enable) { $method = 'render'.ucfirst($action); - array_push($prepends, $this->{$method}()); + $prepends[] = $this->{$method}(); } } diff --git a/src/Grid/Displayers/DropdownActions.php b/src/Grid/Displayers/DropdownActions.php index 94cec8692..6fbe6669c 100644 --- a/src/Grid/Displayers/DropdownActions.php +++ b/src/Grid/Displayers/DropdownActions.php @@ -54,7 +54,7 @@ protected function prependDefaultActions() continue; } - array_push($this->default, $this->{'render'.ucfirst($action)}()); + $this->default[] = $this->{'render' . ucfirst($action)}(); } } diff --git a/src/Grid/Displayers/Limit.php b/src/Grid/Displayers/Limit.php index 3b165971f..cd6f26db6 100644 --- a/src/Grid/Displayers/Limit.php +++ b/src/Grid/Displayers/Limit.php @@ -32,7 +32,7 @@ public function display($limit = 100, $end = '...') $value = array_slice($value, 0, $limit); - array_push($value, $end); + $value[] = $end; return $value; } diff --git a/src/Grid/Tools/Selector.php b/src/Grid/Tools/Selector.php index c5d2411c0..61209d3d2 100644 --- a/src/Grid/Tools/Selector.php +++ b/src/Grid/Tools/Selector.php @@ -187,7 +187,7 @@ public function url($column, $value = null, $add = false) if ($add) { $options = []; } - array_push($options, $value); + $options[] = $value; } if (! empty($options)) { diff --git a/src/Http/Controllers/PermissionController.php b/src/Http/Controllers/PermissionController.php index 4a4e505aa..3e5f9cfcc 100644 --- a/src/Http/Controllers/PermissionController.php +++ b/src/Http/Controllers/PermissionController.php @@ -46,7 +46,7 @@ protected function treeView() $max = 3; if (count($path) > $max) { $path = array_slice($path, 0, $max); - array_push($path, '...'); + $path[] = '...'; } $method = $branch['http_method'] ?: []; diff --git a/src/Show/Field.php b/src/Show/Field.php index e17ced925..143c43a8c 100755 --- a/src/Show/Field.php +++ b/src/Show/Field.php @@ -460,7 +460,7 @@ public function append($val) } if (is_array($v)) { - array_push($v, $val); + $v[] = $val; return $v; } elseif ($v instanceof Collection) { diff --git a/src/Tree/Actions.php b/src/Tree/Actions.php index b08cc6aed..77ef1b05c 100644 --- a/src/Tree/Actions.php +++ b/src/Tree/Actions.php @@ -54,7 +54,7 @@ public function append($action) { $this->prepareAction($action); - array_push($this->appends, $action); + $this->appends[] = $action; return $this; } From d9724c36e977d0ef071b58c0fbd4a7f056dff310 Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 16:20:45 +0800 Subject: [PATCH 2/9] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Exception/Handler.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Exception/Handler.php b/src/Exception/Handler.php index d7adf189a..d00c10fe2 100644 --- a/src/Exception/Handler.php +++ b/src/Exception/Handler.php @@ -75,10 +75,6 @@ public function report(\Throwable $e) */ protected function replaceBasePath(string $path) { - return str_replace( - str_replace('\\', '/', base_path().'/'), - '', - str_replace('\\', '/', $path) - ); + return str_replace(['\\', str_replace('\\', '/', base_path() . '/')], ['/', ''], $path); } } From 19f37469eeb5fe866f02676dd88b95ce4278a6a6 Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 16:26:24 +0800 Subject: [PATCH 3/9] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E6=AF=94=E5=AF=B9=E6=9D=A1=E4=BB=B6=EF=BC=8C=E6=8F=90?= =?UTF-8?q?=E9=AB=98=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Grid/Filter/AbstractFilter.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Grid/Filter/AbstractFilter.php b/src/Grid/Filter/AbstractFilter.php index 52a3451a0..3cf6ed110 100755 --- a/src/Grid/Filter/AbstractFilter.php +++ b/src/Grid/Filter/AbstractFilter.php @@ -559,9 +559,7 @@ protected function buildCondition(...$params) return; } - $column = explode('.', $this->column); - - if (count($column) == 1) { + if (!str_contains($this->column, '.')) { return [$this->query => &$params]; } From 36b83b38ea454905d02215925ebb6736fbc9eb9b Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 16:33:24 +0800 Subject: [PATCH 4/9] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E6=8C=89=E9=92=AE=20HTML=20=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Widgets/DialogTable.php | 4 ++-- src/Widgets/Modal.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Widgets/DialogTable.php b/src/Widgets/DialogTable.php index 126d78e81..4ee6b89ff 100644 --- a/src/Widgets/DialogTable.php +++ b/src/Widgets/DialogTable.php @@ -250,8 +250,8 @@ protected function renderButton() $button = Helper::render($this->button); // 如果没有HTML标签则添加一个 a 标签 - if (! preg_match('/(\<\/[\d\w]+\s*\>+)/i', $button)) { - $button = "{$button}"; + if (! preg_match('/<[^>]+>/', $button)) { + $button = sprintf('%s', $button); } return $button; diff --git a/src/Widgets/Modal.php b/src/Widgets/Modal.php index abd4cdaee..341212fc3 100644 --- a/src/Widgets/Modal.php +++ b/src/Widgets/Modal.php @@ -340,7 +340,7 @@ protected function addLoadRenderableScript() $this->on('show.bs.modal', <<').loading(); - + setTimeout(function () { target.trigger('{$this->target}:load') }, {$this->delay}); @@ -415,8 +415,8 @@ protected function renderButton() $button = Helper::render($this->button); // 如果没有HTML标签则添加一个 a 标签 - if (! preg_match('/(\<\/[\d\w]+\s*\>+)/i', $button)) { - $button = "{$button}"; + if (! preg_match('/<[^>]+>/', $button)) { + $button = sprintf('%s', $button); } return << Date: Sat, 1 Nov 2025 16:41:05 +0800 Subject: [PATCH 5/9] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E6=80=A7?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E9=81=BF=E5=85=8D=E5=9C=A8=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E4=B8=AD=E9=87=8D=E5=A4=8D=E5=90=88=E5=B9=B6=E6=95=B0=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在循环中使用 `array_merge()` 会导致 O(n²) 的时间复杂度。 --- src/Form/Field/Autocomplete.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Form/Field/Autocomplete.php b/src/Form/Field/Autocomplete.php index 576f63dbd..cd553ea5f 100644 --- a/src/Form/Field/Autocomplete.php +++ b/src/Form/Field/Autocomplete.php @@ -133,12 +133,20 @@ public function render() protected function formatGroupOptions() { + $groupOptions = []; + foreach ($this->groups as $group) { if (! array_key_exists('options', $group) || ! array_key_exists('label', $group)) { continue; } - $this->options = array_merge($this->options, $this->formatOptions($group['options'], $group['label'])); + // 先收集所有格式化的选项,避免在循环中重复合并数组 + $groupOptions[] = $this->formatOptions($group['options'], $group['label']); + } + + // 使用展开运算符一次性合并所有数组,性能更优 + if ($groupOptions) { + $this->options = array_merge($this->options, ...$groupOptions); } $this->groups = []; From 2252201104b6fb55afda74a04cf3d9084fad0a99 Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 16:41:18 +0800 Subject: [PATCH 6/9] =?UTF-8?q?perf:=20=E4=BD=BF=E7=94=A8=E5=B1=95?= =?UTF-8?q?=E5=BC=80=E8=BF=90=E7=AE=97=E7=AC=A6=E6=9B=BF=E4=BB=A3=20array?= =?UTF-8?q?=5Fmerge=EF=BC=8C=E6=80=A7=E8=83=BD=E6=9B=B4=E4=BC=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Form/Field/ArrayField.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Form/Field/ArrayField.php b/src/Form/Field/ArrayField.php index df446c45f..08c047b51 100644 --- a/src/Form/Field/ArrayField.php +++ b/src/Form/Field/ArrayField.php @@ -31,7 +31,8 @@ protected function buildRelatedForms() foreach (Helper::array($this->value()) as $key => $data) { if (isset($data['pivot'])) { - $data = array_merge($data, $data['pivot']); + // 使用展开运算符替代 array_merge,性能更优 + $data = [...$data, ...$data['pivot']]; } $forms[$key] = $this->buildNestedForm($key)->fill($data); From 6bef8e812a6da92720f3a75c7beb16690ce67c4a Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 16:58:16 +0800 Subject: [PATCH 7/9] =?UTF-8?q?perf:=20=E6=80=A7=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Form/Concerns/HasFields.php | 3 ++- src/Form/Field/Embeds.php | 12 +++--------- src/Form/Field/HasMany.php | 12 +++--------- src/Form/Field/Text.php | 14 ++++++++------ src/Grid/Concerns/HasComplexHeaders.php | 10 +++++----- src/Support/DatabaseUpdater.php | 6 +++--- src/Support/Helper.php | 17 +++++++++++++---- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/Form/Concerns/HasFields.php b/src/Form/Concerns/HasFields.php index 76da2ab77..6851993be 100644 --- a/src/Form/Concerns/HasFields.php +++ b/src/Form/Concerns/HasFields.php @@ -123,7 +123,8 @@ protected function mergedFields() foreach ($this->fields() as $field) { if ($field instanceof FieldsCollection) { /** @var Field $field */ - $fields = array_merge($fields, $field->mergedFields()); + // 使用array_push和展开运算符,避免重复的array_merge调用 + array_push($fields, ...$field->mergedFields()); } else { $fields[] = $field; } diff --git a/src/Form/Field/Embeds.php b/src/Form/Field/Embeds.php index 82c120308..f948f9c31 100755 --- a/src/Form/Field/Embeds.php +++ b/src/Form/Field/Embeds.php @@ -125,15 +125,9 @@ public function getValidator(array $input) * 'extra.end_atend' => "$label[end_at]" * ] */ - $attributes = array_merge( - $attributes, - $this->formatValidationAttribute($input, $field->label(), $column) - ); - - $messages = array_merge( - $messages, - $this->formatValidationMessages($input, $field->getValidationMessages()) - ); + $attributes += $this->formatValidationAttribute($input, $field->label(), $column); + + $messages += $this->formatValidationMessages($input, $field->getValidationMessages()); } if (empty($rules)) { diff --git a/src/Form/Field/HasMany.php b/src/Form/Field/HasMany.php index d9be9ef8e..8dd126252 100755 --- a/src/Form/Field/HasMany.php +++ b/src/Form/Field/HasMany.php @@ -154,15 +154,9 @@ public function getValidator(array $input) $rules[$column] = $fieldRules; } - $attributes = array_merge( - $attributes, - $this->formatValidationAttribute($input, $field->label(), $column) - ); - - $messages = array_merge( - $messages, - $this->formatValidationMessages($input, $field->getValidationMessages()) - ); + $attributes += $this->formatValidationAttribute($input, $field->label(), $column); + + $messages += $this->formatValidationMessages($input, $field->getValidationMessages()); } Arr::forget($rules, NestedForm::REMOVE_FLAG_NAME); diff --git a/src/Form/Field/Text.php b/src/Form/Field/Text.php index 445ec0fe4..75033a63b 100755 --- a/src/Form/Field/Text.php +++ b/src/Form/Field/Text.php @@ -161,16 +161,18 @@ protected function formatOptions($options) $original = []; $toReplace = []; - foreach ($options as $key => &$value) { + foreach ($options as $key => $value) { if (is_array($value)) { $subArray = $this->formatOptions($value); - $value = $subArray['options']; - $original = array_merge($original, $subArray['original']); - $toReplace = array_merge($toReplace, $subArray['toReplace']); + $options[$key] = $subArray['options']; + + // 使用array_push和展开运算符,避免重复的array_merge + array_push($original, ...$subArray['original']); + array_push($toReplace, ...$subArray['toReplace']); } elseif (preg_match('/function.*?/', $value)) { $original[] = $value; - $value = "%{$key}%"; - $toReplace[] = "\"{$value}\""; + $options[$key] = "%{$key}%"; + $toReplace[] = "\"%{$key}%\""; } } diff --git a/src/Grid/Concerns/HasComplexHeaders.php b/src/Grid/Concerns/HasComplexHeaders.php index b65a9caba..123fd75aa 100644 --- a/src/Grid/Concerns/HasComplexHeaders.php +++ b/src/Grid/Concerns/HasComplexHeaders.php @@ -74,11 +74,11 @@ protected function sortHeaders() $headersColumns = $this->complexHeaders = $this->columns = []; foreach ($originalHeaders as $header) { - $headersColumns = array_merge( - $headersColumns, - $tmp = $header->getColumnNames()->toArray() - ); - foreach ($tmp as &$name) { + $columnNames = $header->getColumnNames(); + + // 直接使用Collection,避免转换为数组和重复的array_merge + foreach ($columnNames as $name) { + $headersColumns[] = $name; if ($column = $originalColumns->get($name)) { $this->columns[$name] = $column; } diff --git a/src/Support/DatabaseUpdater.php b/src/Support/DatabaseUpdater.php index adfdfd2d2..eecf2e9c0 100644 --- a/src/Support/DatabaseUpdater.php +++ b/src/Support/DatabaseUpdater.php @@ -139,16 +139,16 @@ public function getClassFromFile($file) // Prefix and suffix string to prevent unterminated comment warning $tokens = token_get_all('/**/'.$buffer.'/**/'); - if (strpos($buffer, '{') === false) { + if (!str_contains($buffer, '{')) { continue; } - for (; $i < count($tokens); $i++) { + for ($iMax = count($tokens); $i < $iMax; $i++) { /* * Namespace opening */ if ($tokens[$i][0] === T_NAMESPACE) { - for ($j = $i + 1; $j < count($tokens); $j++) { + for ($j = $i + 1, $jMax = count($tokens); $j < $jMax; $j++) { if ($tokens[$j] === ';') { break; } diff --git a/src/Support/Helper.php b/src/Support/Helper.php index d62873ecc..4b3766e57 100755 --- a/src/Support/Helper.php +++ b/src/Support/Helper.php @@ -763,13 +763,20 @@ public static function prepareHasOneRelation(Collection $fields, array &$input) foreach ($relations as $first => $v) { if (isset($input[$first])) { - foreach ($input[$first] as $key => $value) { + $firstValue = $input[$first]; + + // 先处理数组值 + foreach ($firstValue as $key => $value) { if (is_array($value)) { $input["$first.$key"] = $value; } } - $input = array_merge($input, Arr::dot([$first => $input[$first]])); + // 使用Arr::dot展开并直接赋值,避免array_merge + $dotted = Arr::dot([$first => $firstValue]); + foreach ($dotted as $dottedKey => $dottedValue) { + $input[$dottedKey] = $dottedValue; + } } } } @@ -896,10 +903,12 @@ public static function arraySet(&$array, $key, $value) } $keys = explode('.', $key); - $default = null; + $keysCount = count($keys); - while (count($keys) > 1) { + // 缓存count()结果,避免在循环中重复调用 + while ($keysCount > 1) { $key = array_shift($keys); + $keysCount--; if (! isset($array[$key]) || (! is_array($array[$key]) && ! $array[$key] instanceof \ArrayAccess)) { $array[$key] = []; From 16177e81ed9a768a4f488c6c12936d29de514f07 Mon Sep 17 00:00:00 2001 From: Shine Date: Sat, 1 Nov 2025 17:04:08 +0800 Subject: [PATCH 8/9] =?UTF-8?q?fix(security):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=BD=9C=E5=9C=A8=E7=9A=84=E5=AE=89=E5=85=A8=E9=A3=8E=E9=99=A9?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Form/Field/Fieldset.php | 2 +- src/Form/Field/UploadField.php | 2 +- src/Grid/Column/Filter/Between.php | 24 +++++++++---------- src/Grid/Column/Filter/Equal.php | 2 +- src/Grid/Column/Filter/In.php | 4 ++-- src/Http/Controllers/EditorMDController.php | 2 +- src/Http/Controllers/PermissionController.php | 4 ++-- src/Http/Controllers/TinymceController.php | 2 +- src/Show/Field.php | 4 ++-- src/Support/Helper.php | 6 ++--- 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Form/Field/Fieldset.php b/src/Form/Field/Fieldset.php index 7a94fa8ab..320188381 100644 --- a/src/Form/Field/Fieldset.php +++ b/src/Form/Field/Fieldset.php @@ -10,7 +10,7 @@ class Fieldset public function __construct() { - $this->name = uniqid('fieldset-'); + $this->name = uniqid('fieldset-', true); } public function start($title) diff --git a/src/Form/Field/UploadField.php b/src/Form/Field/UploadField.php index b6cfd36be..a1d0190cf 100755 --- a/src/Form/Field/UploadField.php +++ b/src/Form/Field/UploadField.php @@ -312,7 +312,7 @@ public function sequenceName() */ protected function generateUniqueName(UploadedFile $file) { - return md5(uniqid()).'.'.$file->getClientOriginalExtension(); + return md5(uniqid('', true)).'.'.$file->getClientOriginalExtension(); } /** diff --git a/src/Grid/Column/Filter/Between.php b/src/Grid/Column/Filter/Between.php index 010d396a2..c2df195bd 100644 --- a/src/Grid/Column/Filter/Between.php +++ b/src/Grid/Column/Filter/Between.php @@ -18,8 +18,8 @@ class Between extends Filter public function __construct() { $this->class = [ - 'start' => uniqid('column-filter-start-'), - 'end' => uniqid('column-filter-end-'), + 'start' => uniqid('column-filter-start-', true), + 'end' => uniqid('column-filter-end-', true), ]; } @@ -175,20 +175,20 @@ public function render()