Composer 是什么？Composer 是一个 PHP 包管理的系统，现在越来越多的 PHP 使用 Composer 来管理包。比如 FastAdmin、 ThinkPHP、Laravel 等都是用 Composer 进行 php 包的管理。安装Windows Installer这是将 Composer 安装在你机器上的最简单的方法。下载并且运行 Composer-Setup.exe，它将安装最新版本的 Composer ，并设置好系统的环境变量，因此你可以在任何目录下直接使用 composer 命令。配置中国镜像修改 composer 的全局配置文件（推荐方式）打开命令行窗口（windows用户）或控制台（Linux、Mac 用户）并执行如下命令composer config -g repo.packagist composer https://packagist.phpcomposer.com镜像列表国内也很多开发者使用 Composer，但由于不可控因素，官方的服务器常常连接不上。所以这里收集了一下国内镜像列表。（先后次序会不定期调整）镜像名地址赞助商/地区阿里云 Composer 镜像https://mirrors.aliyun.com/composer/阿里云腾讯云 Composer 镜像https://mirrors.cloud.tencent.com/composer/腾讯云PHP 国内 Composer 镜像https://packagist.phpcomposer.com 华为云 Composer 镜像https://repo.huaweicloud.com/repository/php/华为云解除镜象如果需要解除镜像并恢复到 packagist 官方源，请执行以下命令composer config -g --unset repos.packagist基本使用查看帮助composer require -h创建一个项目composer create-project 公司名/项目名 项目路径/* 创建 laravel 项目 */ composer create-project laravel/laravel=5.5.* ./laravel /* 创建 ThinkPHP 项目 */ composer create-project topthink/ThinkPHP=5.1.* ./tp5查找可安装的包到官方包管理网站搜索https://packagist.org 或者 composer search 包名composer search laravel下载/更新# 下载安装，当项目有composer.json时，但是还没有vendor目录时使用 composer install # 更新 composer update # 更新指定包 composer update monolog/monolog安装一个包composer require 包名 版本composer require laravel/laravel ">=5.5"移除一个包composer remove 包名composer remove laravel/laravel升级 composercomposer self-update查看配置composer config -gl指定php版本不同版本的php兼容性不一样，比如php8.0以上的就不支持一下语法，这时我们需要安装多个版本的php，当然在执行compsoer时也需要设置不同的版本。# 部分项目会需要指定php版本运行 /usr/bin/php73 /usr/local/bin/composer create-project laravel/laravel自动加载Composer 还准备了一个自动加载文件，它可以加载 Composer 下载的库中所有的类文件。你只需要将下面这行代码添加到你项目的引导文件中，或者某些旧框架没有使用 composer ，可以在类中单独引入，之后该文件就可以使用composer加载的包<?php …… require 'vendor/autoload.php';composer.json 架构只要你有一个 composer.json 文件在目录中，那么整个目录就是一个包。当你添加一个 require 到项目中，你就是在创建一个依赖于其它库的包。你的项目和库之间唯一的区别是，你的项目是一个没有名字的包。{ "name": "topthink/framework", "description": "The ThinkPHP Framework.", "type": "project", "keywords": [ "framework", "thinkphp", "ORM" ], "homepage": "http://thinkphp.cn/", "license": "Apache-2.0", "authors": [ { "name": "liu21st", "email": "liu21st@gmail.com" }, { "name": "yunwuxin", "email": "448901948@qq.com" } ], "require": { "php": ">=7.2.5", "ext-json": "*", "ext-mbstring": "*", "league/flysystem": "^1.1.4", "league/flysystem-cached-adapter": "^1.0", "psr/log": "~1.0", "psr/container": "~1.0", "psr/simple-cache": "^1.0", "psr/http-message": "^1.0", "topthink/think-orm": "^2.0", "topthink/think-helper": "^3.1.1" }, "require-dev": { "mikey179/vfsstream": "^1.6", "mockery/mockery": "^1.2", "phpunit/phpunit": "^7.0", "guzzlehttp/psr7": "^2.1.0" }, "autoload": { "files": [], "psr-4": { "think\\": "src/think/" } }, "autoload-dev": { "psr-4": { "think\\tests\\": "tests/" } }, "minimum-stability": "dev", "prefer-stable": true, "config": { "sort-packages": true } }包名 name包的名称，它包括供应商名称和项目名称，使用 / 分隔。monolog/monologigorw/event-source对于需要发布的包（库），这是必须填写的。描述 description一个包的简短描述。通常这个最长只有一行。对于需要发布的包（库），这是必须填写的。版本 version它应该符合 'X.Y.Z' 或者 'vX.Y.Z' 的形式， -dev、-patch、-alpha、-beta 或 -RC 这些后缀是可选的。在后缀之后也可以再跟上一个数字。1.0.00.2.51.0.0-dev1.0.0-alpha31.0.0-beta21.0.0-RC5通常，我们能够从 VCS (git, svn, hg) 的信息推断出包的版本号，在这种情况下，我们建议忽略 version。Packagist 使用 VCS 仓库， 因此 version 定义的版本号必须是真实准确的。 自己手动指定的 version，最终有可能在某个时候因为人为错误造成问题。安装类型 type包的安装类型，默认为 library。包的安装类型，用来定义安装逻辑。如果你有一个包需要一个特殊的逻辑，你可以设定一个自定义的类型。这可以是一个 symfony-bundle，一个 wordpress-plugin 或者一个 typo3-module。这些类型都将是具体到某一个项目，而对应的项目将要提供一种能够安装该类型包的安装程序。composer 原生支持以下4种类型：library: 这是默认类型，它会简单的将文件复制到 vendor 目录。project: 这表示当前包是一个项目，而不是一个库。例：框架应用程序 Symfony standard edition，内容管理系统 SilverStripe installer 或者完全成熟的分布式应用程序。使用 IDE 创建一个新的工作区时，这可以为其提供项目列表的初始化。metapackage: 当一个空的包，包含依赖并且需要触发依赖的安装，这将不会对系统写入额外的文件。因此这种安装类型并不需要一个 dist 或 source。composer-plugin: 一个安装类型为 composer-plugin 的包，它有一个自定义安装类型，可以为其它包提供一个 installler。详细请查看 自定义安装类型。仅在你需要一个自定义的安装逻辑时才使用它。建议忽略这个属性，采用默认的 library。关键字 keywords该包相关的关键词的数组。这些可用于搜索和过滤。【 可选 】loggingeventsdatabaseredistemplating项目主页 homepage该项目网站的 URL 地址。【 可选 】版本发布时间 time版本发布时间。【 可选 】必须符合 YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS 格式。许可协议 license包的许可协议，它可以是一个字符串或者字符串数组。【 可选 】最常见的许可协议的推荐写法（按字母排序）：Apache-2.0BSD-2-ClauseBSD-3-ClauseBSD-4-ClauseGPL-2.0GPL-2.0+GPL-3.0GPL-3.0+LGPL-2.1LGPL-2.1+LGPL-3.0LGPL-3.0+MIT但强烈建议提供此内容。更多许可协议的标识符请参见 SPDX Open Source License Registry。对于闭源软件，你必须使用 "proprietary" 协议标识符。{ "license": "MIT" }对于一个包，当允许在多个许可协议间进行选择时（"disjunctive license"），这些协议标识符可以被指定为数组。{ "license": [ "LGPL-2.1", "GPL-3.0+" ] }另外它们也可以由 "or" 分隔，并写在括号中：{ "license": "(LGPL-2.1 or GPL-3.0+)" }同样，当有多个许可协议需要结合使用时（"conjunctive license"），它们应该被 "and" 分隔，并写在括号中。作者 authors包的作者。这是一个对象数组。【 可选】 但强烈建议提供此内容。这个对象必须包含以下属性：name: 作者的姓名，通常使用真名。email: 作者的 email 地址。homepage: 作者主页的 URL 地址。role: 该作者在此项目中担任的角色（例：开发人员 或 翻译）。一个实例：{ "authors": [ { "name": "Nils Adermann", "email": "naderman@naderman.de", "homepage": "http://www.naderman.de", "role": "Developer" }, { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "http://seld.be", "role": "Developer" } ] }支持 support获取项目支持的向相关信息对象。【可选】这个对象必须包含以下属性：email: 项目支持 email 地址。issues: 跟踪问题的 URL 地址。forum: 论坛地址。wiki: Wiki 地址。irc: IRC 聊天频道地址，类似于 irc://server/channel。source: 网址浏览或下载源。{ "support": { "email": "support@example.org", "irc": "irc://irc.freenode.org/composer" } }依赖 require require-dev下面提到的所有对象，都应该是 包名 到 版本 的映射对象。【 可选 】{ "require": { "monolog/monolog": "1.0.*" } }require 和 require-dev 还支持稳定性标签（@，仅针对“root 包”）。这允许你在 minimum-stability 设定的范围外做进一步的限制或扩展。例：如果你想允许依赖一个不稳定的包，你可以在一个包的版本约束后使用它，或者是一个空的版本约束内使用它。实例：{ "require": { "monolog/monolog": "1.0.*@beta", "acme/foo": "@dev" } }require必须的软件包列表，除非这些依赖被满足，否则不会完成安装。require-dev (root-only)这个列表是为开发或测试等目的，额外列出的依赖。“root 包”的 require-dev 默认是会被安装的。# 添加--no-dev 跳过 require-dev 中包的安装 composer install --no-dev composer update --no-devconflict此列表中的包与当前包的这个版本冲突。它们将不允许同时被安装。请注意，在 conflict 中指定类似于 <1.0, >= 1.1 的版本范围时，这表示它与小于1.0 并且 同时大等于1.1的版本冲突，这很可能不是你想要的。在这种情况下你可能想要表达的是 <1.0 | >= 1.1 。replace这个列表中的包将被当前包取代。这使你可以 fork 一个包，以不同的名称和版本号发布，同时要求依赖于原包的其它包，在这之后依赖于你 fork 的这个包，因为它取代了原来的包。这对于创建一个内部包含子包的主包也非常的有用。例如 symfony/symfony 这个主包，包含了所有 Symfony 的组件，而这些组件又可以作为单独的包进行发布。如果你 require 了主包，那么它就会自动完成其下各个组件的任务，因为主包取代了子包。注意，在使用上述方法取代子包时，通常你应该只对子包使用 self.version 这一个版本约束，以确保主包仅替换掉子包的准确版本，而不是任何其他版本。provideList of other packages that are provided by this package. This is mostly useful for common interfaces. A package could depend on some virtual logger package, any library that implements this logger interface would simply list it in provide.自动加载 autoloadPHP autoloader 的自动加载映射。目前支持PSR-0自动加载、PSR-4自动加载、类映射生成和文件包含。 PSR-4是推荐的方法 ，因为它更易于使用（添加类时无需重新生成自动加载器）。PSR-4在psr-4键下，您定义了从名称空间到路径的映射，相对于包根。当自动加载类似Foo\\Bar\\Baz的类时，指向目录src/的名称空间前缀Foo\\意味着自动加载程序将查找名为src/Bar/Baz的文件。与 PSR-0 相反，前缀（Foo\\）不在文件路径中。命名空间前缀必须以\结尾，以避免类似前缀之间的冲突。例如，Foo将匹配FooBar名称空间中的类，因此后面的反斜杠可以解决问题：Foo\\和FooBar\\是不同的。在安装/更新期间，PSR-4引用全部合并到一个key=>value数组中，该数组可以在生成的文件vendor/composer/automoad_psr4.php中找到。{ "autoload": { "psr-4": { "Monolog\\": "src/", "Vendor\\Namespace\\": "" } } }如果需要在多个目录中搜索同一前缀，可以将其指定为数组，如下所示：{ "autoload": { "psr-4": { "Monolog\\": ["src/", "lib/"] } } }如果您想在回退目录中查找任何名称空间，可以使用空前缀，如：{ "autoload": { "psr-4": { "": "src/" } } }PSR-0在 psr-0 key 下你定义了一个命名空间到实际路径的映射（相对于包的根目录）。注意，这里同样支持 PEAR-style 方式的约定（与命名空间不同，PEAR 类库在类名上采用了下划线分隔）。命名空间的申明应该以 \ 结束 ，以确保 autoloader 能够准确响应。Foo 将会与 FooBar 匹配，然而以反斜杠结束就可以解决这样的问题， Foo\ 和 FooBar\ 将会被区分开来。当自动加载类似Foo\\Bar\\Baz的类时，指向目录src/的名称空间前缀Foo\\意味着自动加载程序将查找名为src/Bar/Baz的文件。在 install/update 过程中，PSR-0 引用都将被结合为一个单一的键值对数组，存储至 vendor/composer/autoload_namespaces.php 文件中。{ "autoload": { "psr-0": { "Monolog\\": "src/", "Vendor\\Namespace\\": "src/", "Vendor_Namespace_": "src/" } } }如果你需要搜索多个目录中一个相同的前缀，你可以将它们指定为一个数组，例：{ "autoload": { "psr-0": { "Monolog\\": "src/", "Vendor\\Namespace\\": "src/", "Vendor_Namespace_": "src/" } } }PSR-0 方式并不仅限于申明命名空间，也可以是精确到类级别的指定。这对于只有一个类在全局命名空间的类库是非常有用的（如果 php 源文件也位于包的根目录）。例如，可以这样申明：{ "autoload": { "psr-0": { "UniqueGlobalClass": "" } } }如果你想设置一个目录作为任何命名空间的备用目录，你可以使用空的前缀，像这样：{ "autoload": { "psr-0": { "UniqueGlobalClass": "" } } }Classmapclassmap 引用的所有组合，都会在 install/update 过程中生成，并存储到 vendor/composer/autoload_classmap.php 文件中。这个 map 是经过扫描指定目录（同样支持直接精确到文件）中所有的 .php 和 .inc 文件里内置的类而得到的。你可以用 classmap 生成支持支持自定义加载的不遵循 PSR-0/4 规范的类库。要配置它指向需要的目录，以便能够准确搜索到类文件。{ "autoload": { "classmap": ["src/", "lib/", "Something.php"] } }Files如果你想要明确的指定，在每次请求时都要载入某些文件，那么你可以使用 'files' autoloading。通常作为函数库的载入方式（而非类库）。{ "autoload": { "files": ["src/MyLibrary/functions.php"] } }autoload-dev (root-only)本节允许为开发目的定义自动加载规则。运行测试套件所需的类不应包含在主自动加载规则中，以避免在生产中以及其他人将您的包用作依赖项时污染自动加载程序。因此，最好为单元测试使用专用路径，并将其添加到自动加载开发部分中。{ "autoload": { "psr-4": { "MyLibrary\\": "src/" } }, "autoload-dev": { "psr-4": { "MyLibrary\\Tests\\": "tests/" } } }config (root-only)下面的这一组选项，仅用于项目，即type类型为project的。支持以下选项：process-timeout: 默认为 300。处理进程结束时间，例如：git 克隆的时间。Composer 将放弃超时的任务。如果你的网络缓慢或者正在使用一个巨大的包，你可能要将这个值设置的更高一些。use-include-path: 默认为 false。如果为 true，Composer autoloader 还将在 PHP include path 中继续查找类文件。preferred-install: 默认为 auto。它的值可以是 source、dist 或 auto。这个选项允许你设置 Composer 的默认安装方法。github-protocols: 默认为 ["git", "https", "ssh"]。从 http://github.com 克隆时使用的协议优先级清单，因此默认情况下将优先使用 git 协议进行克隆。你可以重新排列它们的次序，例如，如果你的网络有代理服务器或 git 协议的效率很低，你就可以提升 https 协议的优先级。github-oauth: 一个域名和 oauth keys 的列表。 例如：使用 {"http://github.com": "oauthtoken"} 作为此选项的值， 将使用 oauthtoken 来访问 github 上的私人仓库，并绕过 low IP-based rate 的 API 限制。vendor-dir: 默认为 vendor。通过设置你可以安装依赖到不同的目录。bin-dir: 默认为 vendor/bin。如果一个项目包含二进制文件，它们将被连接到这个目录。cache-dir: unix 下默认为 $home/cache，Windows 下默认为 C:\Users\<user>\AppData\Local\Composer。用于存储 composer 所有的缓存文件。cache-files-dir: 默认为 $cache-dir/files。存储包 zip 存档的目录。cache-repo-dir: 默认为 $cache-dir/repo。存储 composer 类型的 VCS（svn、github、bitbucket） repos 目录。cache-vcs-dir: 默认为 $cache-dir/vcs。此目录用于存储 VCS 克隆的 git/hg 类型的元数据，并加快安装速度。cache-files-ttl: 默认为 15552000（6个月）。默认情况下 Composer 缓存的所有数据都将在闲置6个月后被删除，这个选项允许你来调整这个时间，你可以将其设置为0以禁用缓存。cache-files-maxsize: 默认为 300MiB。Composer 缓存的最大容量，超出后将优先清除旧的缓存数据，直到缓存量低于这个数值。prepend-autoloader: 默认为 true。如果设置为 false，composer autoloader 将不会附加到现有的自动加载机制中。这有时候用来解决与其它自动加载机制产生的冲突。autoloader-suffix: 默认为 null。Composer autoloader 的后缀，当设置为空时将会产生一个随机的字符串。optimize-autoloader Defaults to false. Always optimize when dumping the autoloader.github-domains: 默认为 "[http://github.com"]。一个 github mode 下的域名列表。这是用于GitHub的企业设置。notify-on-install: 默认为 true。Composer 允许资源仓库定义一个用于通知的 URL，以便有人从其上安装资源包时能够得到一个反馈通知。此选项允许你禁用该行为。discard-changes: 默认为 false，它的值可以是 true、false 或 stash。这个选项允许你设置在非交互模式下，当处理失败的更新时采用的处理方式。true 表示永远放弃更改。"stash" 表示继续尝试。Use this for CI servers or deploy scripts if you tend to have modified vendors.{ "config": { "bin-dir": "bin" } }bin该属性用于标注一组应被视为二进制脚本的文件，他们会被软链接到（config 对象中的）bin-dir 属性所标注的目录，以供其他依赖包调用。详细请查看 二进制供应库和 vendor/bin 目录。
php session_start(): Failed to read session data: user (path:XXX)
当我们想用数据库来存储session时，可调用session_set_save_handler()函数，把session对应的不同方法的实现封装进去，但是在封装完之后，进行调用时，有可能发生 warning：session_start(): Failed to read session data: user (path:XXX) ，由于在网上没法找到对应的解决办法，博主查了一下PHP手册，发现问题出在session_set_save_handler()的第三个参数read回调函数上。手册原文：通过 read 回调函数返回的现有会话数据（使用特殊的序列化格式存储）， PHP 会自动反序列化数据并且填充 $_SESSION 超级全局变量。如果会话中有数据，read 回调函数必须返回将会话数据编码（序列化）后的字符串。 如果会话中没有数据，read 回调函数返回空字符串。所以，在read()方法的实现时，如果返回的数据库查询结果是数组的形式，要对其进行序列化操作；如果返回的数据查询为空则返回空字符串；博主就在read()方法的return $result; 改成return serialize($result);