liuhairui 1 年之前
父節點
當前提交
4ec846bf8b

+ 1 - 0
thinkphp/.gitignore

@@ -2,3 +2,4 @@
 /vendor
 .idea
 .DS_Store
+/.vscode

+ 1 - 1
thinkphp/README.md

@@ -60,7 +60,7 @@ ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
 
 本项目包含的第三方源码和二进制文件之版权信息另行标注。
 
-版权所有Copyright © 2006-2022 by ThinkPHP (http://thinkphp.cn)
+版权所有Copyright © 2006-2024 by ThinkPHP (http://thinkphp.cn)
 
 All rights reserved。
 

+ 1 - 1
thinkphp/base.php

@@ -9,7 +9,7 @@
 // | Author: liu21st <liu21st@gmail.com>
 // +----------------------------------------------------------------------
 
-define('THINK_VERSION', '5.0.25');
+define('THINK_VERSION', '5.0.27');
 define('THINK_START_TIME', microtime(true));
 define('THINK_START_MEM', memory_get_usage());
 define('EXT', '.php');

+ 7 - 0
thinkphp/library/think/Collection.php

@@ -360,6 +360,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @param  mixed $offset 键名
      * @return bool
      */
+    #[\ReturnTypeWillChange]
     public function offsetExists($offset)
     {
         return array_key_exists($offset, $this->items);
@@ -371,6 +372,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @param  mixed $offset 键名
      * @return mixed
      */
+    #[\ReturnTypeWillChange]
     public function offsetGet($offset)
     {
         return $this->items[$offset];
@@ -383,6 +385,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @param  mixed $value  值
      * @return void
      */
+    #[\ReturnTypeWillChange]
     public function offsetSet($offset, $value)
     {
         if (is_null($offset)) {
@@ -398,6 +401,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @param  mixed $offset 键名
      * @return void
      */
+    #[\ReturnTypeWillChange]
     public function offsetUnset($offset)
     {
         unset($this->items[$offset]);
@@ -408,6 +412,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @access public
      * @return int
      */
+    #[\ReturnTypeWillChange]
     public function count()
     {
         return count($this->items);
@@ -418,6 +423,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @access public
      * @return ArrayIterator
      */
+    #[\ReturnTypeWillChange]
     public function getIterator()
     {
         return new ArrayIterator($this->items);
@@ -428,6 +434,7 @@ class Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSeria
      * @access public
      * @return array
      */
+    #[\ReturnTypeWillChange]
     public function jsonSerialize()
     {
         return $this->toArray();

+ 1 - 1
thinkphp/library/think/Lang.php

@@ -201,7 +201,7 @@ class Lang
         } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
             // 自动侦测浏览器语言
             preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
-            $langSet     = strtolower($matches[1]);
+            $langSet     = strtolower($matches[1] ?? '');
             $acceptLangs = Config::get('header_accept_lang');
 
             if (isset($acceptLangs[$langSet])) {

+ 1 - 1
thinkphp/library/think/Loader.php

@@ -613,7 +613,7 @@ class Loader
         if ($type) {
             $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
                 return strtoupper($match[1]);
-            }, $name);
+            }, $name ?? '');
 
             return $ucfirst ? ucfirst($name) : lcfirst($name);
         }

+ 16 - 3
thinkphp/library/think/Model.php

@@ -1267,10 +1267,18 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
             $data = $this->data;
         } else {
             $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) {
+                if (is_numeric($a) && is_numeric($b)) {
+                    if (strcmp($a, $b) !== 0) {
+                        return 1;
+                    }
+                    if ($a == $b) {
+                        return 0;
+                    }
+                }
                 if ((empty($a) || empty($b)) && $a !== $b) {
                     return 1;
                 }
-                return is_object($a) || $a != $b ? 1 : 0;
+                return is_object($a) || $a !== $b ? 1 : 0;
             });
         }
 
@@ -1309,10 +1317,10 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
     }
 
     /**
-     * 字段值(延迟)增长
+     * 字段值(延迟)减少
      * @access public
      * @param string  $field    字段名
-     * @param integer $step     增长
+     * @param integer $step     减少
      * @param integer $lazyTime 延时时间(s)
      * @return integer|true
      * @throws Exception
@@ -2268,27 +2276,32 @@ abstract class Model implements \JsonSerializable, \ArrayAccess
     }
 
     // JsonSerializable
+    #[\ReturnTypeWillChange]
     public function jsonSerialize()
     {
         return $this->toArray();
     }
 
     // ArrayAccess
+    #[\ReturnTypeWillChange]
     public function offsetSet($name, $value)
     {
         $this->setAttr($name, $value);
     }
 
+    #[\ReturnTypeWillChange]
     public function offsetExists($name)
     {
         return $this->__isset($name);
     }
 
+    #[\ReturnTypeWillChange]
     public function offsetUnset($name)
     {
         $this->__unset($name);
     }
 
+    #[\ReturnTypeWillChange]
     public function offsetGet($name)
     {
         return $this->getAttr($name);

+ 8 - 1
thinkphp/library/think/Paginator.php

@@ -128,7 +128,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
         }
         $url = $path;
         if (!empty($parameters)) {
-            $url .= '?' . http_build_query($parameters, null, '&');
+            $url .= '?' . http_build_query($parameters, '', '&');
         }
         return $url . $this->buildFragment();
     }
@@ -304,6 +304,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
      * @return Traversable An instance of an object implementing <b>Iterator</b> or
      * <b>Traversable</b>
      */
+    #[\ReturnTypeWillChange]
     public function getIterator()
     {
         return new ArrayIterator($this->items->all());
@@ -314,6 +315,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
      * @param mixed $offset
      * @return bool
      */
+    #[\ReturnTypeWillChange]
     public function offsetExists($offset)
     {
         return $this->items->offsetExists($offset);
@@ -324,6 +326,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
      * @param mixed $offset
      * @return mixed
      */
+    #[\ReturnTypeWillChange]
     public function offsetGet($offset)
     {
         return $this->items->offsetGet($offset);
@@ -334,6 +337,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
      * @param mixed $offset
      * @param mixed $value
      */
+    #[\ReturnTypeWillChange]
     public function offsetSet($offset, $value)
     {
         $this->items->offsetSet($offset, $value);
@@ -345,6 +349,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
      * @return void
      * @since 5.0.0
      */
+    #[\ReturnTypeWillChange]
     public function offsetUnset($offset)
     {
         $this->items->offsetUnset($offset);
@@ -353,6 +358,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
     /**
      * Count elements of an object
      */
+    #[\ReturnTypeWillChange]
     public function count()
     {
         return $this->items->count();
@@ -388,6 +394,7 @@ abstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, J
     /**
      * Specify data which should be serialized to JSON
      */
+    #[\ReturnTypeWillChange]
     public function jsonSerialize()
     {
         return $this->toArray();

+ 1 - 1
thinkphp/library/think/Request.php

@@ -1091,7 +1091,7 @@ class Request
         foreach ($filters as $filter) {
             if (is_callable($filter)) {
                 // 调用函数或者方法过滤
-                $value = call_user_func($filter, $value);
+                $value = call_user_func($filter, $value ?? '');
             } elseif (is_scalar($value)) {
                 if (false !== strpos($filter, '/')) {
                     // 正则过滤

+ 2 - 2
thinkphp/library/think/Template.php

@@ -925,11 +925,11 @@ class Template
                                     $args[1] = str_replace('###', $name, $args[1]);
                                     $name    = "$fun($args[1])";
                                 } else {
-                                    $name = "$fun($name,$args[1])";
+                                    $name = "$fun($name ?? '',$args[1])";
                                 }
                             } else {
                                 if (!empty($args[0])) {
-                                    $name = "$fun($name)";
+                                    $name = "$fun($name ?? '')";
                                 }
                             }
                         }

+ 2 - 2
thinkphp/library/think/Validate.php

@@ -931,10 +931,10 @@ class Validate
         if (is_string($rule) && strpos($rule, ',')) {
             list($rule, $param) = explode(',', $rule);
         } elseif (is_array($rule)) {
-            $param = isset($rule[1]) ? $rule[1] : null;
+            $param = $rule[1] ?? 0;
             $rule  = $rule[0];
         } else {
-            $param = null;
+            $param = 0;
         }
         return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param);
     }

+ 1 - 1
thinkphp/library/think/console/output/Ask.php

@@ -299,7 +299,7 @@ class Ask
             $width = max(array_map('strlen', array_keys($this->question->getChoices())));
 
             foreach ($this->question->getChoices() as $key => $value) {
-                $this->output->writeln(sprintf("  [<comment>%-${width}s</comment>] %s", $key, $value));
+                $this->output->writeln(sprintf("  [<comment>%-{$width}s</comment>] %s", $key, $value));
             }
         }
 

+ 1 - 1
thinkphp/library/think/console/output/Descriptor.php

@@ -219,7 +219,7 @@ class Descriptor
             $width = $this->getColumnWidth($description->getCommands());
 
             foreach ($description->getCommands() as $command) {
-                $this->writeText(sprintf("%-${width}s %s", $command->getName(), $command->getDescription()), $options);
+                $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
                 $this->writeText("\n");
             }
         } else {

+ 1 - 0
thinkphp/library/think/db/Query.php

@@ -480,6 +480,7 @@ class Query
             $result = Cache::get($guid);
         }
         if (false === $result) {
+            $result = [];
             if (isset($this->options['field'])) {
                 unset($this->options['field']);
             }

+ 1 - 5
thinkphp/library/think/db/builder/Mysql.php

@@ -109,12 +109,8 @@ class Mysql extends Builder
             }
         }
 
-//        if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
-//            throw new Exception('not support data:' . $key);
-//        }
-        if ($strict && !preg_match('/^[\w\.\*\x00-\xff]+$/', $key)) {
+        if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
             throw new Exception('not support data:' . $key);
-
         }
         if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)`.\s]/', $key))) {
             $key = '`' . $key . '`';

+ 1 - 2
thinkphp/library/think/db/builder/Sqlsrv.php

@@ -13,7 +13,6 @@ namespace think\db\builder;
 
 use think\db\Builder;
 use think\db\Expression;
-use think\Exception;
 
 /**
  * Sqlsrv数据库驱动
@@ -96,7 +95,7 @@ class Sqlsrv extends Builder
             }
         }
 
-        if ($strict && !preg_match('/^[\w\.\*\x7f-\xff]+$/', $key)) {
+        if ($strict && !preg_match('/^[\w\.\*]+$/', $key)) {
             throw new Exception('not support data:' . $key);
         }
         if ('*' != $key && ($strict || !preg_match('/[,\'\"\*\(\)\[.\s]/', $key))) {

+ 1 - 1
thinkphp/library/think/model/relation/HasMany.php

@@ -164,7 +164,7 @@ class HasMany extends Relation
             }
         }
         $localKey = $this->localKey ?: $this->parent->getPk();
-        return $this->query->whereExp($this->foreignKey, '=' . $this->parent->getTable() . '.' . $localKey)->fetchSql()->count();
+        return $this->query->alias( 'count_table')->whereExp( 'count_table.' . $this->foreignKey, '=' . $this->parent->getTable() . '.' . $localKey)->fetchSql()->count();
     }
 
     /**

+ 1 - 1
thinkphp/library/think/model/relation/MorphOne.php

@@ -211,7 +211,7 @@ class MorphOne extends Relation
 
         $model = new $this->model();
 
-        return $model->save() ? $model : false;
+        return $model->save($data) ? $model : false;
     }
 
     /**

+ 7 - 1
thinkphp/library/think/session/driver/Redis.php

@@ -42,6 +42,7 @@ class Redis extends SessionHandler
      * @return bool
      * @throws Exception
      */
+    #[\ReturnTypeWillChange]
     public function open($savePath, $sessName)
     {
         // 检测php环境
@@ -69,6 +70,7 @@ class Redis extends SessionHandler
      * 关闭Session
      * @access public
      */
+    #[\ReturnTypeWillChange]
     public function close()
     {
         $this->gc(ini_get('session.gc_maxlifetime'));
@@ -83,6 +85,7 @@ class Redis extends SessionHandler
      * @param string $sessID
      * @return string
      */
+    #[\ReturnTypeWillChange]
     public function read($sessID)
     {
         return (string) $this->handler->get($this->config['session_name'] . $sessID);
@@ -92,9 +95,10 @@ class Redis extends SessionHandler
      * 写入Session
      * @access public
      * @param string $sessID
-     * @param String $sessData
+     * @param string $sessData
      * @return bool
      */
+    #[\ReturnTypeWillChange]
     public function write($sessID, $sessData)
     {
         if ($this->config['expire'] > 0) {
@@ -110,6 +114,7 @@ class Redis extends SessionHandler
      * @param string $sessID
      * @return bool
      */
+    #[\ReturnTypeWillChange]
     public function destroy($sessID)
     {
         return $this->handler->del($this->config['session_name'] . $sessID) > 0;
@@ -121,6 +126,7 @@ class Redis extends SessionHandler
      * @param string $sessMaxLifeTime
      * @return bool
      */
+    #[\ReturnTypeWillChange]
     public function gc($sessMaxLifeTime)
     {
         return true;

+ 2 - 2
thinkphp/library/traits/controller/Jump.php

@@ -38,8 +38,8 @@ trait Jump
     {
         if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) {
             $url = Request::instance()->server('HTTP_REFERER');
-        } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) {
-            $url = Url::build($url);
+        } elseif ('' !== $url && !strpos($url ?? '', '://') && 0 !== strpos($url ?? '', '/')) {
+            $url = Url::build($url ?? '');
         }
 
         $type = $this->getResponseType();

+ 1 - 1
thinkphp/tpl/think_exception.tpl

@@ -68,7 +68,7 @@
                         break;
                 }
 
-                $result[] = is_int($key) ? $value : "'{$key}' => {$value}";
+                $result[] = is_int($key) ? $value : sprintf('\'%s\' => %s', htmlentities($key), $value);
             }
 
             return implode(', ', $result);