关于composer:Composer-源管理

剽窃至此,节俭搜寻工夫 ,不便开发时复制 以后我的项目切换 composer config repo.packagist composer {source}全局切换 composer config -g repo.packagist composer {source}全局查看配置 composer config -g -l 以后我的项目查看配置 composer config -l禁用默认源镜像命令 composer config -g secure-http false 可用镜像 (1)、composerhttps://packagist.org (2)、phpcomposerhttps://packagist.phpcomposer.com (3)、阿里云composer镜像源https://mirrors.aliyun.com/composer (4)、腾讯云composer镜像源https://mirrors.cloud.tencent.com/composer (5)、华为云composer镜像源https://mirrors.huaweicloud.com/repository/php

April 24, 2023 · 1 min · jiezi

关于composer:ubuntu安装composer

1.下载composer.pharwget https://getcomposer.org/compo...1 2.重命名composer.phar为composermv composer.phar composer1 3.减少可执行权限chmod +x composer1 4.当初能够通过./composer 命令运行composer,但这只仅限于在当前目录运行。要想全局应用,composer ,要设置把它为全局变量。找到composer文件,把它移到/usl/local/bin 目录,这样就能够在全局应用composer 命令。sudo mv composer /usr/local/bin //有管理员权限的不必加sudo1 5.输出composer测试/:/ composer __ / _/ _ __ _ / / / / `__ / / / __/ / ___// /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ /_/Composer version 1.7-dev (c2fbbe3b86788eb507a0f4f45f9fdc623ca579c4) 2018-03-29 21:36:46 Usage: command [options] [arguments] Options: -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version ...

October 25, 2022 · 3 min · jiezi

关于composer:Ubuntu-安装Composer并全局配置国内镜像源

参考阿里巴巴开源镜像站 在装置Composer前咱们须要装置必要的依赖软件 sudo apt updatesudo apt install wget php-cli php-zip unzip 下载安装器装置composer wget -O composer-setup.php https://getcomposer.org/installer装置composer sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer实现 当初就能够应用composer了 查看更新 composer self-update 全局配置阿里镜像源 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

December 24, 2021 · 1 min · jiezi

关于composer:在centos7服务器上安装Composer

一、参考链接阿里巴巴开源镜像站   在centos7服务器上安装Composer 先装置扩大包 用阿里镜像比拟快 wget https://mirrors.aliyun.com/composer/composer.phar如图 可能须要批改权限 chmod 755 composer.phar 把composer.phar挪动到环境下让其变成可执行 mv composer.phar /usr/local/bin/composer 查看版本 composer -V 最初配置下阿里镜像源 全局配置 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/      

December 23, 2021 · 1 min · jiezi

关于composer:配置阿里云-Composer-全量镜像

一、参考链接阿里巴巴开源镜像站-OPSX镜像站-阿里云开发者社区 (aliyun.com) 阿里云 Composer 全量镜像 Composer 中文网 / Packagist 中国全量镜像 (phpcomposer.com) PHP: Windows 下的 PHP 安装程序工具 - Manual Composer 装置与应用 | 菜鸟教程 (runoob.com) Packagist / Composer 中国全量镜像 (pkg.xyz) 二、Composer 全量镜像介绍Composer 是 PHP 的一个依赖管理工具。它容许你申明我的项目所依赖的代码库,它会在你的我的项目中为你装置他们。 三、阿里云 Composer 全量镜像安装操作1️ Windows零碎下装置PHP开发环境下载链接:PHP For Windows: Binaries and sources Releases 下载最新线程平安版PHP zip压缩包,解压缩后放在想要装置的门路下 2️测试PHP是否装置胜利C:\Users\xybdiy>php -vPHP 8.1.1 (cli) (built: Dec 15 2021 10:31:43) (ZTS Visual C++ 2019 x64)Copyright (c) The PHP GroupZend Engine v4.1.1, Copyright (c) Zend TechnologiesC:\Users\xybdiy>3️ 办法一:装置 Composer(取其一即可)Windows零碎下装置Composer-Setup.exe ...

December 21, 2021 · 2 min · jiezi

关于composer:使用版本管理创建composer私有库

一、背景多个我的项目有雷同代码   二、创立1、初始化一个裸仓 xxxx.git 2、git clone 到本地 3、在根目录下创立src目录,composer的一种格局标准,composer库的代码在该目录下开发 4、初始化composer配置,composer init 生成 composer.json,交互式【一路回车】生成一些配置和属性,也能够复制别的出名第三方库composer.json文件进行批改。最终如下, { "name": "galaxy/platform", "description": "xxxxxx库", "type": "library", "require": { "php":">=5.6" }, "license": "MIT", "autoload": { "psr-4": { "Galaxy\\": "src/" } }, "authors": [ { "name": "xxxxx", "email": "xxxxxx@qq.com" } ]}其中比拟重要的是require::库对环境的要求,以及领导不同的库的加载版本autoload:主动加载配置,这里应用psr-4标准,定义Galaxy作为跟命令空间,映射src目录 5、创立src/Traits/RpcTrait.php 其命名空间即为 Galaxy\Traits\RpcTrait 6、提交代码,推送版本   三、引入1、在我的项目代码的composer.json文件引入如下配置 "repositories": { "galaxy/platform": { "type": "git", "url": "xxxx.git" }}, 其中galaxy/platform是咱们自定义的包名,也是最初装置完的目录构造,vendor/galaxy/platform执行composer update 即可,实质是调用git clone或git pull配置的公有库仓库地址,获取代码笼罩vendor/galaxy/platform,所以这里是须要有克隆和拉取公有库代码的权限,如果仓库是ssh协定,则须要先密钥受权仓库是https或http协定,则须要登录凭证,也就是仓库托管平台的账号密码;如果是http还额定须要在composer.json减少配置【在config中减少"secure-http": false】 留神:默认拉取是master分支的最新版本,这里能够指定分支以及版本。通过以上操作后,composer.json会默认生成require配置【"galaxy/platform": "dev-master"】,其中key是包名,值是固定格局dev-{{分支}}#{{版本hash或标签}},如果咱们指定了某个版本。就会拉取指定版本的公有库代码,如图   四、应用像失常的库应用,如图   五、开发与迭代1、没有第三方依赖的代码,能够间接编码,在公有库我的项目中进行开发测试,这里能够在src目下建Tests目录,写测试用例,或者创立Demo目录,写调用示例; 2、有第三方依赖的代码,目前我不晓得如何间接在公有库我的项目中进行开发,不过我想到一种办法,先在业务我的项目代码中对公有库进行开发,开发测试通过后,将代码笼罩公有库本人的仓库代码进行提交推送,而后在业务我的项目代码,执行composer update   六、疑难1、有第三方依赖的公有库代码,是否有更好的开发方式?

November 9, 2021 · 1 min · jiezi

关于composer:composer-安装及使用

1、装置:composer的装置就不必多说了,官网下载 或者间接yum装置。 2、常用命令:1)配置为国内镜像仓库 composer config -g repo.packagist composer https://packagist.phpcomposer.com2)装置工具库 require/install /*composer require 包名 版本号,例如装置thinkphp*/composer require topthink/think5.0.0/*或者*/设置composer.json后执行 composer install3)卸载工具库remove/update /*composer remove 包名,例如 移除thinkphp(此命令用于移除依赖关系,文件需手动删除)*/composer remove topthink/think/*或者,composer update,此命令也可用于更新工具库的版本*/删除composer.json里包名的列表后执行 composer update4)创立我的项目create-project ,例如,基于thinkphp依赖创立名为tp5pro的我的项目: composer create-project topthink/think tp5pro --prefer-dist5)composer常用命令: composer init 以交互方式填写composer.json文件信息composer install 从当前目录读取composer.json文件,解决依赖关系,并装置到vendor目录下composer update 获取依赖的最新版本,降级composer.lock文件composer require 增加新的依赖包到composer.json文件中并执行更新composer search 在以后我的项目中搜寻依赖包composer show 列举所有可用的资源包composer validate 检测composer.json文件是否无效composer self-update 将composer工具更新到最新版本composer create-project 基于composer创立一个新的我的项目composer dump-autoload 在增加新的类和目录映射时更新autoloader查看更多:https://docs.phpcomposer.com/03-cli.htmlhttps://blog.csdn.net/lamp_yang_3533/article/details/802331563、可用包列表:可能很多刚接触composer工具的phper和我一样在纠结这个问题,composer里有哪些包能够装置,在哪看composer的全部包列表。 https://packagist.org 这个网站,如下图: 在这里间接关键字匹配搜寻即可~~~ 4、composer.json和composer.lock区别在应用composer后目录中会呈现2个文件,composer.lock和composer.json,当初来说说这两个文件的作用。 1)composer.json composer.json文件中保留的是咱们装置的组件及组件的版本要求。 2)comopser.lock composer.lock文件中保留的是组件及其依赖的具体版本,在多人协同开发的状况下,这个文件能很好的解决组件不同而产生的问题。在应用composer install的时候是不会批改composer.lock这个文件,所以会把这个文件也放入版本治理中,其它人在应用时只须要composer install就能够了。而应用composer update后批改这个文件。 综上所述: composer.lock这个文件次要是解决在协同开发中组件及其依赖的版本记录,避免不同人应用的组件及依赖版本不同。

October 28, 2021 · 1 min · jiezi

关于composer:composer-autoload自动加载性能优化-dumpautoload

composer 提供的 autoload 机制使得咱们组织代码和引入新类库十分不便,然而也使我的项目的性能降落了不少 。 composer autoload 慢的次要起因在于来自对 PSR-0 和 PSR-4 的反对,加载器失去一个类名时须要到文件系统里查找对应的类文件地位,能够看到 PSR-4 或者 PSR-0 的主动加载都是一件很累人的事儿。根本是个 O(n2) 的复杂度。另外有一大堆 is_file之类的 IO 操作所以性能堪忧。所以明天咱们就来聊聊composer主动加载的优化,聊之前咱们先来简略说一下composer主动加载的原理。以下是相干局部源码: <phpclass ClassLoader{ private $vendorDir; // PSR-4 private $prefixLengthsPsr4 = array(); private $prefixDirsPsr4 = array(); private $fallbackDirsPsr4 = array(); // PSR-0 private $prefixesPsr0 = array(); private $fallbackDirsPsr0 = array(); private $useIncludePath = false; private $classMap = array(); private $classMapAuthoritative = false; private $missingClasses = array(); private $apcuPrefix; private static $registeredLoaders = array(); public function __construct($vendorDir = null) { $this->vendorDir = $vendorDir; } /** * Finds the path to the file where the class is defined. * * @param string $class The name of the class * * @return string|false The path if found, false otherwise */ public function findFile($class) { // class map lookup if (isset($this->classMap[$class])) { return $this->classMap[$class]; } if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { return false; } if (null !== $this->apcuPrefix) { $file = apcu_fetch($this->apcuPrefix.$class, $hit); if ($hit) { return $file; } } $file = $this->findFileWithExtension($class, '.php'); // Search for Hack files if we are running on HHVM if (false === $file && defined('HHVM_VERSION')) { $file = $this->findFileWithExtension($class, '.hh'); } if (null !== $this->apcuPrefix) { apcu_add($this->apcuPrefix.$class, $file); } if (false === $file) { // Remember that this class does not exist. $this->missingClasses[$class] = true; } return $file; } private function findFileWithExtension($class, $ext) { // PSR-4 lookup $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; $first = $class[0]; if (isset($this->prefixLengthsPsr4[$first])) { $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { if (file_exists($file = $dir . $pathEnd)) { return $file; } } } } } // PSR-4 fallback dirs foreach ($this->fallbackDirsPsr4 as $dir) { if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { return $file; } } // PSR-0 lookup if (false !== $pos = strrpos($class, '\\')) { // namespaced class name $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); } else { // PEAR-like class name $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; } if (isset($this->prefixesPsr0[$first])) { foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { if (0 === strpos($class, $prefix)) { foreach ($dirs as $dir) { if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { return $file; } } } } } // PSR-0 fallback dirs foreach ($this->fallbackDirsPsr0 as $dir) { if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { return $file; } } // PSR-0 include paths. if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { return $file; } return false; }} ?>从源码中咱们看出,Compsoer\ClassLoader 会优先查看 autoload_classmap 中所有生成的注册类。如果在classmap 中没有发现再 fallback 到 psr-4 而后 psr-0。所以咱们就从classmap动手。 ...

September 23, 2021 · 3 min · jiezi

关于composer:composer-install-和updaterequire的使用

简略解释:composer install:如有 composer.lock 文件,间接装置,否则从 composer.json 装置最新扩大包和依赖;composer update:从 composer.json 装置最新扩大包和依赖;composer update vendor/package:从 composer.json 或者对应包的配置,并更新到最新;composer require new/package:增加装置 new/package, 能够指定版本,如: composer require new/package ~2.5.开发我的项目中应用流程:一、新我的项目流程:创立 composer.json,并增加依赖到的扩大包;运行 composer install,装置扩大包并生成 composer.lock;提交 composer.lock 到代码版本控制器中,如:git;二、我的项目协作者拉取我的项目 : 克隆我的项目后,根目录下间接运行 composer install 从 composer.lock 中装置 指定版本 的扩大包以及其依赖; 三、为我的项目增加新扩大包:应用 composer require new/package 增加扩大包;提交更新后的 composer.json 和 composer.lock 到代码版本控制器中,如:git;参考: composer install https://docs.phpcomposer.com/...composer update https://docs.phpcomposer.com/...

June 23, 2021 · 1 min · jiezi

关于composer:使用PSR4配合composer-autoload-自动加载文件夹

require 文件很麻烦,应用PSR-4搭配composer一次加载,终生受用。感觉相似java中的import了,本人先记录一下最近了解的。 用composer治理本人的包吧 装置composer 这个不多赘述 英文版教程 中文版教程 PSR-4标准PSR-4-autoloader 构建我的项目目录|-project |-src |-View.php |-app |-Tools.php |-composer.json 下面门路的View.php在project/src/View.php 中,其余同理,View 和 Tools 只是为了做演示用的。构建composer.json关上创立的composer.json文件输出,这里拿monolog做例子。 { "require": { "monolog/monolog": "1.2.*"}} 用composer加载包在目录所在的命令行中输出 #linux全局装置下应用该命令composer install#windows下应用参考后面的composer教程composer.phar install 加载结束之后你的目录应该是这样的 |-project |-src |-View.php |-app |-Tools.php |-vendor |-composer/* composer目录上面的文件不在赘述 |-monolog/* 同理 |-autoload.php |-composer.json |-composer.lock 测试加载的monolog包在project目录下创立一个index.php #index.php<?php/** * Created by PhpStorm. * User: EasyChris<chris@afox.cc> * Date: 2017/1/22 * Time: 10:50 *///引入autoload.php文件require_once 'vendor/autoload.php';//测试monlog$log = new MonologLogger('name');$log->pushHandler(new MonologHandlerStreamHandler('app.log', MonologLogger::WARNING));$log->addWarning('Foo');echo 'success'; 在浏览器外面拜访该文件地址,通常应该是http://127.0.0.1/project/index.php ...

November 12, 2020 · 1 min · jiezi

关于composer:Mac环境安装Composer

你能够在本人的我的项目中申明所依赖的内部工具库(libraries),Composer 会帮你装置这些依赖的库文件。 Composer也能够治理我的项目。总的来说Composer是一个基于PHP的版本控制、项目管理的工具。 英文官网:https://getcomposer.org/英文镜像:https://packagist.org中武官网:https://www.phpcomposer.com/中文镜像:https://pkg.phpcomposer.com/ 装置Composer装置Composer只须要做到两点 1、下载安装 composer.phar2、配置中文镜像 具体如下:1、全局装置,官网下载最新版本的 composer.phar2、验证,在文件目录执行 确保PHP可用且版本b大于5.6 php -vcomposer版本号和日期与官网统一即可 php composer.phar -v3、最初,设置成全局命令 mv composer.phar /usr/local/bin/composer到此已装置实现 4、接下来配置中文镜像 全局替换: composer config -g repo.packagist composer https://packagist.phpcomposer.com部分配置:(仅对当前目录无效) composer config repo.packagist composer https://packagist.phpcomposer.com上述命令将会在以后我的项目中的 composer.json 文件的开端主动增加镜像的配置信息(你也能够本人手工增加): "repositories": {     "packagist": {         "type": "composer",         "url": "https://packagist.phpcomposer.com"     } }以MongoDB拓展为例,在当前目录下减少composer.json文件,内容如下 {    "require": {        "monolog/monolog": "1.2.*"    }}执行上述命令后,变成 ...

November 8, 2020 · 1 min · jiezi

关于composer:phpstorm使用

1、win10环境搭建a.配置composer命令行环境下载php和composer、配置环境变量,方便使用composer环境:编写composer.bat @php "%~dp0composer.phar" config -g repo.packagist composer https://mirrors.aliyun.com/composer/b.vagrant装置环境初始化homestead环境 迅雷下载https://vagrantcloud.com/laravel/boxes/homestead/versions/10.0.0/providers/virtualbox.boxvagrant box add --name homestead/10.0 homestead_virtualbox.box

July 31, 2020 · 1 min · jiezi

关于composer:phpstorm使用

1、win10环境搭建a.配置composer命令行环境下载php和composer、配置环境变量,方便使用composer环境:编写composer.bat @php "%~dp0composer.phar" config -g repo.packagist composer https://mirrors.aliyun.com/composer/b.vagrant装置环境初始化homestead环境 迅雷下载https://vagrantcloud.com/laravel/boxes/homestead/versions/10.0.0/providers/virtualbox.boxvagrant box add --name homestead/10.0 homestead_virtualbox.box

July 31, 2020 · 1 min · jiezi

composer-win10在局域网通过代理上网的情况下无法安装包解决方案

两种办法,依据状况设置: 全局,设置(权限治理严格的状况下,用第二种) set http_proxy=http://代理网址set https_proxy=代理网址以后用户下设置环境变量: 配置实现后倡议重启命令工具后应用。

July 14, 2020 · 1 min · jiezi

composer镜像源更换为阿里云

官网: https://developer.aliyun.com/... 全局替换 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/composer clear-cache # 此步选择性操作,革除所有 package 缓存。以后我的项目替换 cd 我的项目目录composer config repo.packagist composer https://mirrors.aliyun.com/composer/

July 13, 2020 · 1 min · jiezi

如何实现一个属于自己的composer代码包

前言对于开发的小伙伴们来说,代码包已经是开发过程中的家常便饭了。比如,PHP有composer,Java有maven,前端有npm,yarn,Mac程序安装有brew,Linux程序安装有yum。使用这些包,可以便于我们很好的管理代码引入的外部代码组件,有助于我们提高开发效率,同时也有助于我们代码管理更加优雅。下文主要就是分享个人自定义一个composer代码包,代码仅仅是作为演示示例,没有实际效果。同时也会不断更新,大家可以关注关注。原文地址 具体实现创建一个远程git代码仓库。创建代码仓库,我是选择的GitHub作为远程仓库。创建好后,我们直接拉取到本地。后面的所有代码都是在该仓库下进行的。具体创建仓库和拉取代码就不做演示。 创建源码目录我们在仓库(为了方便描述,后文便用项目一词来替代该词)下面,创建一个src的目录,用于存储我们实际的代码。 编写实际代码下面这个文件,是后面实际需要调用的类。具体的演示代码,可以通过演示代码仓库进行查看。主要的作用就是利用工厂模式,Cache去调用实际的缓存类。 <?php// composer演示代码declare(strict_types=1);// 这里的命名空间根据自己情况填写,后面生成的composer.json文件需要使用该命名空间。namespace Bruce;use Bruce\Client\Redis;class Cache{ public $redisHandle = ''; public function __construct() { $this->redisHandle = new Redis(); }}创建好代码仓库中的所有文件,这时候我们就可以开始生成composer.json文件了。 生成composer.json配置文件下面就是具体生成的过程了,记住一定要在项目的根目录下面使用composer init命令。 composer initWelcome to the Composer config generatorThis command will guide you through creating your composer.json config.#项目命名空间Package name (<vendor>/<name>) [bruce_redis/redis]: bruce_redis/redis#项目描述Description []: composer test#作者信息Author [卡二条 <2665274677@qq.com>, n to skip]: 卡二条 <2665274677@qq.com>#输入最低稳定版本Minimum Stability []: dev#项目类型Package Type (e.g. library, project, metapackage, composer-plugin) []: library#授权类型License []: Define your dependencies.#依赖信息Would you like to define your dependencies (require) interactively [yes]? yes#如果需要依赖,则输入要安装的依赖Search for a package: phpEnter the version constraint to require (or leave blank to use the latest version): >=7.0Search for a package: Would you like to define your dev dependencies (require-dev) interactively [yes]? yesSearch for a package: phpEnter the version constraint to require (or leave blank to use the latest version): >=7.0Search for a package: { "name": "bruce_redis/redis", "description": "composer test", "type": "library", "require": { "php": ">=7.0" }, "require-dev": { "php": ">=7.0" }#确认构建项目,生成composer.jsonDo you confirm generation [yes]? yesWould you like the vendor directory added to your .gitignore [yes]? yesWould you like to install dependencies now [yes]? yesLoading composer repositories with package informationUpdating dependencies (including require-dev)Nothing to install or updateWriting lock fileGenerating autoload files这里需要注意一下<vendor>/<name>配置项根据composer中文网翻译的是供应商名称和项目名称。实际指的就是,你在其他项目中安装该composer包时,在你其他项目的vendor目录下面名称。例如,我将示例的代码的该配置项,设置为bruce_redis/redis。我再其他项目使用该包,展现的形式就是下图的效果。 ...

June 18, 2020 · 2 min · jiezi

使用Gitlab搭建Composer-私有化仓库

在Gitlab 中新建私有化仓库选择一个仓库名称 mkdir prirepos进入目录 cd prirepos使用 composer init 初始化私有化仓库 composer init一路回车,或者填写你想要的参数或者组件包 { "name": "chenghuiyong/prirepos", "authors": [ { "name": "会勇禾口王", "email": "chenghuiyong1987@gmail.com" } ], "require": {}}这里,参考Laravel 框架组件化实现,举例实际应用场景:如果你的项目正在使用migration 管理数据迁移和模型文件,当项目越大,数据迁移和模型文件就会变得越来越多,突然一天,另外一个项目也想使用该项目中的模型文件,本办法就是复制粘贴。如果有1000个文件,那么你复制1000次... 下面推荐使用私有化仓库的方法,既做到共用,也保障安全,然后通过composer 引入到新的项目中。 此时,我们私有仓库就会变成这样的结构设计 - .git- database - migrations - 2014_10_12_100000_create_users_table- src - Models - User.php - ServiceProvider.php- vendor- composer.json- composer.lock于是,你的composer.json可能就会这样 { "name": "prirepos/model", "description": "The Prirepos Laravel Models", "type": "library", "require": { "illuminate/database": "^6.0|^7.0", "illuminate/support": "^6.0|^7.0", "illuminate/console": "^6.0|^7.0", }, "license": "MIT", "authors": [ { "name": "会勇禾口王", "email": "chenghuiyong1987@gmail.com" } ], "autoload": { "psr-4": { "Prirepos\\Model\\": "src/" } }, "extra": { "laravel": { "providers": [ "Prirepos\\Model\\ServiceProvider" ] } }, "config": { "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true, "repositories": { "packagist": { "type": "composer", "url": "https://mirrors.aliyun.com/composer/" } }}重要的ServiceProvider.php包含 ...

November 2, 2019 · 2 min · jiezi

Yii2-composer安装慢的解决办法

在yii中引用php的开源项目用composer已经很方便了,引用前端的开源项目也有composer的插件fxp-asset和Asset Packagist 以前yii默认采用前者,现在新的yii2模版默认采用后者,后者的作者就很厉害了,貌似是个重度yii用户,看来是被fxp-asset的执行缓慢给弄急眼了,所以自己搞了个更新的方法。言归正传:所以更快速的安装方式就是 Asset Packagist https://asset-packagist.org 其实就是2步: 在config中关闭fxp-asset的调用在源列表中加入asset-packagist库的配置"config": { "process-timeout": 1800, "fxp-asset": { "enabled": false } }, "repositories": [ { "type": "composer", "url": "https://asset-packagist.org" }]需要注意的是,yii在yii\base\Application 中定义vendor路径的时候也定义了bower和npm路径: /** * Sets the directory that stores vendor files. * @param string $path the directory that stores vendor files. */ public function setVendorPath($path) { $this->_vendorPath = Yii::getAlias($path); Yii::setAlias('@vendor', $this->_vendorPath); Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower'); Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm'); }这就和asset-packagist的默认安装路径有了差别解决办法:重新定义yii中的bower和npm路径 ...

September 10, 2019 · 1 min · jiezi

compoer基本操作详解

原文转自微信公众号: qq1005349393 Composer介绍Composer 是 PHP 的一个<font color='red'>包依赖</font>管理工具。我们可以在项目中声明所依赖的外部工具库,Composer 会帮你安装这些依赖的库文件,有了它,我们就可以很轻松的使用一个命令将其他人的优秀代码引用到我们的项目中来。Composer 默认情况下不是全局安装,而是基于指定的项目的某个目录中(例如 vendor)进行安装。Composer 需要 PHP 5.3.2+ 以上版本,且需要开启 openssl。Composer 可运行在 Windows 、 Linux 以及 OSX 平台上。 Composer安装1.Windows安装Wondows 平台上,我们只需要下载 Composer-Setup.exe 后,一步步安装即可。需要注意的是你需要开启 openssl 配置,我们打开 php 目录下的 php.ini,将 extension=php_openssl.dll 前面的分号去掉就可以了。安装完成之后,检测是否安装成功。可以使用 composer --version命令查看,如下图:2.Linux安装 // 下载composer文件php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"// 使用PHP解释器安装composerphp composer-setup.php// 移动到系统可执行文件目录,方便我们后期直接使用composer命令进行全局调用 mv composer.phar /usr/local/bin/composer3.Mac Os安装 ------直接安装// 下载并安装curl -sS https://getcomposer.org/installer | php// 移动到可执行文件目录,便于全局调用sudo mv composer.phar /usr/local/bin/composer------使用Mac上面的brew包管理工具安装brew install composer// 检测是否安装成功composer --version4.如何切换composer镜像源现在阿里处理自己的composer镜像源,并且能够做到与Packagist官网实时同步,推荐使用阿里的composer镜像源. // 切换镜像源composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/// 取消配置composer config -g --unset repos.packagist// 只针对当前项目切换镜像源(非全局切换)composer config repo.packagist composer https://mirrors.aliyun.com/composer/// 取消当前项目的镜像源composer config --unset repos.packagist5.composer更新composer的更新可以使用自身的命令来更新 ...

September 8, 2019 · 1 min · jiezi

ComposerPackagist-最新国内源

前言由于近期laravel-china那边出现不稳定的情况(暂不清楚是否已恢复),导致无法正常使用composer。 云服务商packagist.phpcomposer.compackagist.laravel-china.org以上的服务出现不稳定(暂不清楚是否已恢复),国内各大云服务商已提供相关服务支持 建议:在更改配置源之前,推荐先执行 composer clearcache 清除缓存若项目之前已通过其他源安装,务必删除 composer.lock 以及 vendor 目录,重新生成。阿里云提供实时同步,5秒更新 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/华为云composer config -g repos.packagist composer https://repo.huaweicloud.com/repository/php/腾讯云composer config -g repos.packagist composer https://mirrors.cloud.tencent.com/composer/备用wudi/swoole-ide-helper 作者搭建 composer config -g repos.packagist composer https://php.cnpkg.org

July 3, 2019 · 1 min · jiezi

composer-服务器安装扩展失败版本过低的-升级过程

ps : 服务器 配置Linux VM-0-9-ubuntu 4.4.0-91-generic #114-Ubuntu SMP Tue Aug 8 11:56:56 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux1. 失败经历安装 easyswoole 的过程中,发现无法通过 composer 安装 报错信息如下: ubuntu@VM-0-9-ubuntu:~/demo/easyswoole$ composer require easyswoole/easyswoole=3.x./composer.json has been createdLoading composer repositories with package informationUpdating dependencies (including require-dev)Installation failed, deleting ./composer.json. [ErrorException] "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? require [--dev] [--prefer-source] [--prefer-dist] [--no-plugins] [--no-progress] [--no-update] [--update-no-dev] [--update-with-dependencies] [--ignore-platform-reqs] [--sort-packages] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--] [<packages>]..google 一下,没有对应的错误信息。 想着先查看一下 composer 版本 ...

June 19, 2019 · 1 min · jiezi

PHP如何实现阿里云短信sdk灵活应用在项目中

首先安装composer require alibabacloud/sdk接着看alibabacloud官网文档https://packagist.org/package... 示例My_composer_aliyunsms.php<?php// use Swoft\Task\Bean\Annotation\Task;// use AlibabaCloud\Client\AlibabaCloud;// use AlibabaCloud\Client\Exception\ClientException;// use AlibabaCloud\Client\Exception\ServerException;use AlibabaCloud\Client\AlibabaCloud;use AlibabaCloud\Client\Exception\ClientException;use AlibabaCloud\Client\Exception\ServerException;use AlibabaCloud\Ecs\Ecs;/** * 阿里信息发送类 * @Task("ali") */class My_composer_aliyunsms{ /** * 发送短信验证码 */ public function sendCode($config,$phone,$code) { $param = [ 'code' => $code ]; AlibabaCloud::accessKeyClient($config['accessKeyId'], $config['accessSecret']) ->regionId($config['regionId']) ->asGlobalClient(); try { $result = AlibabaCloud::rpcRequest() ->product('Dysmsapi') ->version('2017-05-25') ->action('SendSms') ->method('POST') ->options([ 'query' => [ 'PhoneNumbers' => $phone, 'SignName' => $config['SignName'], 'TemplateCode' => $config['TemplateCode'], 'TemplateParam' => json_encode($param) ], ]) ->request(); return $result->toArray(); } catch (ClientException $e) { echo $e->getErrorMessage() . PHP_EOL; } catch (ServerException $e) { echo $e->getErrorMessage() . PHP_EOL; } }}demo include 'My_composer_aliyunsms.php'; $sms = new My_composer_aliyunsms(); $phone='xxxxxx'; $code='99999'; $config = [ 'accessKeyId' => 'LTAIMje******hS', 'accessSecret' => 'fMuQTLUrKQN******Z2m07', 'SignName' => '****', 'TemplateCode' => 'SMS_****04', 'regionId' => 'cn-hangzhou' ]; $re = $sms->sendCode($config,$phone,$code); var_dump($re);

June 13, 2019 · 1 min · jiezi

PHP如何实现env-文件灵活应用在项目中

首先composer安装composer require vlucas/phpdotenv接着看phpdotenv官方文档https://packagist.org/package... 示例$dotenv = Dotenv\Dotenv::create(__DIR__, '.env');$my_env = $dotenv->load();var_dump($my_env);

June 13, 2019 · 1 min · jiezi

在Repository模式下使用laravel

laravel-repository仓库地址Github Repository文档地址 清晰的目录结构Models只负责定义模型(如:模型关联,scope,get和set attribute等)Repository负责处理这个表相关的所有业务逻辑, 不只是注入model, 相关的redis任何cache都可以注入,代码定位迅速Controllers 只负责处理简单的逻辑,获取转发数据,它应该是 简洁干净 的AppHttpControllerAdmin IndexControllerUserControllerConfigController...Request(所有的request验证类)Admin Index StoreRequestUpdateRequestDestroyRequestUser ...Config ...Request.phpModels (所有的model模型)User(用户相关的所有模型)User.phpUserExt.phpUserMessage.phpConfigConfig.php...BaseModel.phpRepositories (目录结构应与model一致,结构清晰)User(用户相关的所有仓库)UserRepository.phpUserExtRepository.phpUserMessageRepository.php...安装并使用composer require littlebug/laravel-repositorymkdir app/Http/Requests# 创建属于你自己的Request验证基类# 就像下面这个文件关于一键生成代码# 在将命令注入到你的laravel 项目以后# 输入php artisan list# 如果你看到下面这些提示,那么可以开始快速生成代码了!~ core core:controller 生成 Controller {--table=} 指定表名称 [ 指定该参数会通过表生成视图文件 ] {--name=} 指定名称 可以带命名空间 [ --name=Home/IndexController 或者 Home\\IndexController ] {--r=} 指定 Repository 需要从 Repositories 目录开始; 默认使用控制器同名 Repository {--request=} 指定 request 目录; 需要从 Requests 目录开始; 默认使用控制器命名空间 {--pk=} 指定主键名称,默认id core:generate 生成 controller|model|repository|request|views {--table=} 指定表名称 [ 支持指定数据库,例如:log.crontabs ] {--path=} 指定目录 [ 没有传递绝对路径,否则使用相对对路径 从 app/Models 开始 ] {--model=} model名称 默认生成使用表名称生成 core:model # 让我们来试一下# 在commands帮助文档的提示下生成代码# 如果你的项目用到了数据库前缀,不要忘了去database.php中添加,否则会找不到table# 举个栗子,以member_message表为例php artisan core:generate --table=member_message --path=Member --controller=Member/MemberMessageController# 在终端中你可以看到下面的结果文件 [ /Users/wanchao/www/lara-test/app/Models/Member/MemberMessage.php ] 生成成功文件 [ /Users/wanchao/www/lara-test/app/Repositories/Member/MemberMessageRepository.php ] 生成成功文件 [ /Users/wanchao/www/lara-test/app/Http/Requests/Member/MemberMessage/UpdateRequest.php ] 生成成功文件 [ /Users/wanchao/www/lara-test/app/Http/Requests/Member/MemberMessage/DestroyRequest.php ] 生成成功文件 [ /Users/wanchao/www/lara-test/app/Http/Requests/Member/MemberMessage/StoreRequest.php ] 生成成功# 添加路由 routes/web.phpRoute::group(['namespace' => 'Member','prefix' => 'member'], function ($route) { $route->get('index', 'MemberController@indexAction'); $route->get('message', 'MemberMessageController@indexAction');});### 修改MemberMessageController### 在MemberMessageController中dd打印数据public function index(){ $filters = Helper::filter_array(request()->all()); $filters['order'] = 'id desc'; $list = $this->memberMessageRepository->paginate($filters); dd($list);}# 终端php artisan servevist localhost:8001/member/message# 你应该尝试一些你的数据库中存在的表,而不是机械的去复制粘贴我的栗子 ...

June 5, 2019 · 1 min · jiezi

12Laravel全文搜索Elasticsearch-三

使用Elasticsearch搜索引擎,配置ik中文分词,与Laravel模型关联,然后实现搜索的业务逻辑。本篇是结束篇,使用Laravel的Scout扩展包完成搜索功能续上篇,已经安装和配置好了Scout和支持Elastic的扩展包 编辑Article模型,将LaravelScoutSearchable 这个 trait加到你想要做检索的模型,这个trait会注册一个模型观察者来保持模型同步到检索服务的驱动: <?phpnamespace App;use Illuminate\Database\Eloquent\Model;use Laravel\Scout\Searchable;class Article extends Model{ // 引入这个trait,这个trait会注册一个模型观察者来保持模型同步到检索服务的驱动 use Searchable;//... // 定义索引里面的type(类型)-- es中类型相当于mysql中的表 public function searchableAs() { return 'article'; } // 定义有哪些字段需要搜索 public function toSearchableArray() { return [ 'id' => $this->id, 'title' => $this->title, 'content' => $this->content ]; }//...}使用aritsan命令,从mysql导入现有数据到ElasticSearch php artisan scout:import查看一下ElasticSearch中是否存在配置的索引,和导入的数据大小 curl 'localhost:9200/_cat/indices?v'ElasticSearch的一些RESTful api调用方式,可以用来测试数据 查看索引的配置 curl -XGET "http://localhost:9200/mi360?pretty=true"查看文档列表 curl -XGET "http://localhost:9200/mi360/_search?pretty=true"查看指定id=10的文档 curl -XGET "http://localhost:9200/mi360/article/10?pretty=true"ok!导入成功后,开始写搜索业务逻辑了 添加路由 Route::get('/search', 'WelcomeController@search');编辑视图文件中的form表单,提交到路由的地址,并且input表单的name=query <form action="{{ url('/search') }}" class="search fr"> <input type="text" name="query" placeholder="客官,想搜点啥?"> <button type="submit">搜索</button></form>编写控制器 ...

May 29, 2019 · 2 min · jiezi

Composer-中国全量镜像开源了一起让-PHP-社区更繁荣

先上链接:https://github.com/zencodex/c...ZComposer 镜像诞生于2017年3月份,至今已经运行2年多了,这不是一个多么有技术含量的东西,所以简单聊一些开发和解决问题的思路,希望能对你有一点启发。如果你觉得有些收获,请点下鼠标,在 github 上给我1个 star(支持下),谢谢。 安全性,不对原有的json,zip做修改,否则会引起 hash 变化,重新计算 hash 没问题(之前第三方有这么做的),这样带来的问题是,无法对包的安全性做校验,假如有恶意黑镜像,对数据做了修改,就无法判断了。所以 ZComposer 的镜像,所有的包都是和 packagist.org 官方一致的,可以比对 hash ,没有任何修改。稳定性,因为不间断的采集数据,上传数据,中间有一个环节出现差错,就可以导致有问题,所以务必对采集完的包,通过 hash 值做完整性检查。有时候第三方的API策略,或者CDN线路都可能导致出现问题。所以做镜像最大的难点,是稳定性的保障。Webysther/packagist-mirror(官方推荐的镜像开源) fork 自 hirak/packagist-crawler,但这些镜像开源都没有处理dist包,而dist包才是最大/最多的,最值得CDN处理的。ZComposer 开源是全量镜像,包含了对 dist 部分的处理。dist 包还有个 65000上限子目录数 的问题,1年的时间,包的数量都是成倍的增加。软连接的方案是我原创出来的,或许随着包的无限增加,还需要设计其他方案。ZComposer 镜像的安装部署推荐运行主机配置: [x] 内存最好不低于4G[x] 剩余磁盘空间不低于30G$ apt install beanstalkd$ cd composer-mirror$ composer install修改配置参数通常根据自己部署的实际环境,修改参数。详细配置说明详见 config.default.phpcp config.default.php config.php,修改 config.php 中的如下参 /** * distdir 用于存储 zip 包 */ 'distdir' => __DIR__ . '/dist/', /** * 指向 mirrorUrl 对应的 web 实际目录 */ 'cachedir' => __DIR__ . '/cache/', /** * packagistUrl:官方采集源 */ 'packagistUrl' => 'https://packagist.org', /** * 镜像包发布站点, packages.json 入口根域名 */ 'mirrorUrl' => 'https://packagist.laravel-china.org', /** * .json 中 dist 分发 zip 包的CDN域名 */ 'distUrl' => 'https://dl.laravel-china.org/',supervisor 配置sudo vim /etc/supervisor/supervisord.conf,添加如下配置信息: ...

May 27, 2019 · 2 min · jiezi

使用Hyperledger-Fabric和Composer实现区块链应用程序

目前无法绕过技术领域的是区块链话题。但除了加密货币之外,还有更多有趣的应用程序可以带来许多激动人心的软件生态系统。这也适用于Hyperledger项目,该项目提供了一个非常模块化的区块链框架。让我们看看使用Hyperledger Fabric和Composer实现区块链应用程序是多么容易。 关于项目HyperledgerHyperledger是一个umbrella项目的名称,在该项目下开源区块链方法和工具是协同开发的。它由Linux基金会于2015年推出,并享有IBM,英特尔和富士通等软件巨头以及大型社区的热烈参与。Hyperledger的GitHub存储库目前比以往更加活跃。任何人都可以参与开发。 在Hyperledger中,不仅开发了单个区块链框架(或平台)。相反,重点是并行采用多种方法,创造协同效应,可重复使用的组件和灵活性。从Hyperledger概念的角度来看,区块链网络与比特币或以太网等加密货币的代表无法比较。相反,Hyperledger网络的节点分布在参与组织中,这使得私有,许可或联盟区块链网络特别有趣。首先,我们可以忘记公共区块链的工作证明,股权证明和其他共识机制。所涉及的组织从应用程序业务价值和所涉及的信任中作为联合体验证彼此的交易和利益。这也很大程度上解决了可扩展性问题(我们从比特币网络中了解到)并且可以实现高交易吞吐量。 项目Hyperledger的不同区块链方法是Fabric,Burrow,Iroha,Indy和Sawtooth。私有,许可和联合区块链可以与所有这些区块链一起开发,但每种实现都遵循不同的方法。 我们将在本文中详细介绍Fabric,因为它拥有最活跃的社区,并且是最灵活的变体。由于其强大的模块化,fabric是普遍可用的。 “你可以将Hyperledger Fabric视为类似于Apache Web Server”,Linux基金会Hyperledger执行董事Brian Behlendorf说。其他方法更多用于在有限的环境中实施特殊情况。 Hyperledger Fabric ——灵活的区块链应用平台使用Fabric作为平台,可以开发完全独立的分布式分类帐解决方案。Fabric包含可以尽可能自由实现的概念。区块链网络的基础是对所需组织结构的建模。每个参与者都有固定的身份,可以通过颁发的证书来识别自己。除了身份验证之外,还包括授权。使用这种基于角色的系统,可以获得许可区块链中隐私和机密性的灵活方面。对于证书和参与者的管理,可以使用结构证书颁发机构(1.0版之前的成员服务提供者)。 资产的定义(要在区块链上管理的项目)完全取决于区块链应用程序。这些资产,例如来自汽车行业的引擎块由JSON和/或二进制格式的键值对模型定义。 链代码的概念旨在基于资产及其所有者实现业务逻辑。这可用于实现Go,Java或Node.js等语言中的规则,这些规则定义读取权限或资产修改。执行链代码功能可以读取和返回资产和/或创建和修改资产并将它们存储在本地分类帐数据库中。在节点上的本地持久性更改之后,将更改提交给网络(“认可”)并在其他组织接受后插入到区块链中。在以太坊或其他公共区块链平台的背景下,可以将链码与智能合约进行比较。 通道用于实现隐私领域。在最简单的场景中,整个链代码部署在所有参与者加入的单个通道上。但是,为了创建封装区域并仅允许选定的参与者在其中进行通信,可以配置具有受限参与者组的通道。每个通道可以部署不同的链代码,从而可以实现功能隔离。此外,可以使用AES部分或完全加密通道中的通信。 结果,在每个通道中维护一个分布式分类帐,这可以被想象为链接交易的现金簿。每个参与者为他们所属的每个通道保留一份分类帐副本。这为网络中的每个现有信道创建了区块链数据结构。与区块链一样,交易存储在块中,这些块在单个连接列表中成为加密链。 但是,为了向客户端应用程序提供分类帐数据的单独视图,甚至可以执行针对网络的复杂读取请求。由于使用了像CouchDB这样的面向文档的数据库,这是可能的。这为连接到Fabric网络的客户端提供了灵活的数据访问。 使用Composer添加更简单的概念Hyperledger-Composer是Hyperledger生态系统中的工具之一。你可以将其视为Fabric的框架。如果你想开发,构建和管理Fabric网络,那么即使不是强制性的,也是实用的。它引入了基于Fabric的进一步概念,以提供精美的抽象概念。 除资产外,还可以在Composer建模语言中定义网络参与者,交易和事件的方案。每种交易类型的流都通过JavaScript代码在简单的API上实现。访问控制文件可用于限制参与者对某些资源的访问权限。可以在Composer Query Language中定义对分类帐中数据的常用查询,这是一种类似SQL的语言。 然后,必须将所有必需文件打包到.bna文件中的BND(业务网络定义)。然后,可以将此存档安装在现有Fabric网络上。BND的源代码当然可以在我们首选的编辑器中进行本地开发和测试,因此可以通过Git进行版本控制。对于原型设计和演示目的,有Composer Playground。这提供了一个现代,清晰且直观可用的Web界面,可访问Composer CLI的本地配置。使用Playground,你可以轻松创建,安装,测试,编辑,导入和导出BND。 在Composer Playground中,你可以以用户友好的方式安装,修改和测试新的业务网络,而无需先前的样本区块链应用知识(例如车辆生命周期,汽车拍卖或农场动物跟踪)。在设置工具之后,可以在本地完成相同的操作,这样我们就可以在短时间玩游戏后离开托管游乐场。这个游乐场非常适合使用原型验证想法并了解底层的Composer和Fabric模型。 使用案例:引擎块的供应链跟踪为了使用Hyperledger-Fabric和Composer实现私有区块链网络,以汽车行业的发动机组跟踪为例。在这种情况下,有制造商和经销商作为网络参与者。发动机及其安装的车辆显示为资产。制造商和经销商的公司被引入并被识别为网络中的组织。 Fabric链代码应提供以下功能: 1.生产具有唯一序列号的发动机缸体。2.生产后将发动机缸体传送给经销商。3.跟踪车辆的序列号。4.将发动机缸体安装到注册车辆中。下一步是安装所需的工具和设置项目。 开发环境设置和项目创建首先,需要安装文档中列出的Fabric的所有要求。然后我们安装Composer和Composer及其相关工具本身的要求。 然后,最好让自己熟悉新环境。如果我们完全按照上一个链接的说明操作,则fabric-tools现在位于我们的主目录中。通过描述的脚本,我们可以在Docker-Compose中启动一个简单的Fabric网络,获得对等管理员访问权限并停止并再次删除它。首先,我们下载1.1版的Docker镜像并启动网络: export FABRIC_VERSION=hlfv11 && ./downloadFabric.sh && ./startFabric.sh在网络运行时,composer-playground web-UI可以通过composer-playground启动。它使用composer-cli的所有托管配置并访问正在运行的Fabric网络。从现在开始,我们将Fabric视为可配置的平台/基础架构,其状态通过合适的工具进行更改。我们不直接使用Fabric概念开发链代码,权限或任何模型,因为Composer提供了更多优势。 实施功能现在我们在我们选择的目录中创建我们的BND项目。对于Yeoman(使用模板设置项目的代码生成器,如Maven Archtypes),有一个模板(hyperledger-composer:businessnetwork。但是,我已经准备了一个存储库,我们现在也可以使用JavaScript ES6和一些很好的工具。我们应该从开始分支“初始”开始。master分支具有最终版本和工作版本。我们首先克隆存储库的初始分支。 git clone -b initial git@github.com:jverhoelen/fabric-composer-engine-supplychain.git现在我们在我们选择的编辑器中打开文件夹。Visual Studio Code非常适合Composer,因为它具有可安装的语法高亮扩展。稍作修改后你会发现它是一个NPM项目,所以我们从npm install开始安装所有依赖项。使用npm test我们可以运行单元测试,使用npm run lint我们可以测试代码样式,并且使用npm run createArchive我们可以创建the.bna文件,我们以打包格式完成业务网络定义。让我们马上试试看是否一切正常。 然后我们熟悉项目结构。lib文件夹包含实现交易处理器功能的JS文件。当然,我们想测试这个业务逻辑并将我们的单元测试存储在test/文件夹中。模型定义(参与者,资产,交易等)在models/中。 我们想首先为所需的区块链网络建模。为此,我们删除模型文件的内容,并在第一行为其指定一个新的命名空间: namespace org.acme.enginesupplychain我们为参与者制造商和经销商建模,并使用Composer建模语言的继承。我们还希望每个参与者除了姓名外还有一个可选地址。我们将这些属性放入一个概念中: participant Member identified by memberId { o String memberId o String name o Address address optional} participant Manufacturer extends Member {} participant Merchant extends Member {} concept Address { o String country o String city o String street o String streetNo}然后我们介绍我们网络的资产:引擎块和稍后安装引擎的汽车。在这里,我们了解资产和参与者可以互相参考。引用始终指向任何类型的现有资源。我们以小“o”开头的属性总是存在于资源本身中。 ...

May 22, 2019 · 3 min · jiezi

安装composer后报错procopen-fork-failed-Cannot-allocate-memory

1.问题描述:在linux服务器使用composer部署yii项目时,出现“proc_open(): fork failed - Cannot allocate memory” 也就是提示“提示内存不足”,我们可以通过创建swap分区解决这个问题。 2.解决方法:先运行 free -m 看下空间是多少在命令行环境依次运行以下三条命令dd if=/dev/zero of=/var/swap.1 bs=1M count=1024mkswap /var/swap.1swapon /var/swap.1举例:[以下是我在服务器运行的结果]dd if=/dev/zero of=/var/swap.1 bs=1M count=1024 //第一条指令1024+0 records in //这个是返回的内容1024+0 records out //这个是返回的内容1073741824 bytes (1.1 GB) copied, 10.0607 s, 107 MB/s //这个是返回的内容mkswap /var/swap.1 //第二条指令Setting up swapspace version 1, size = 1048572 KiB //这个是返回的内容no label, UUID=f6280c41-21b4-4039-bc3e-c26284b47b0c //这个是返回的内容swapon /var/swap.1 //第三条指令swapon: /var/swap.1: insecure permissions 0644, 0600 suggested. //这个是返回的内容解释:dd 从/dev/zero设备复制出一个1G大小的文件/var/swap.1mkswap 格式化/var/swap.1swapon 将swap分区挂在到文件系统然后输入free -m 查看内存使用量信息最后再次执行composer update就成功了参考的博客有:http://www.zfsphp.com/31.html ...

May 15, 2019 · 1 min · jiezi

后端相关技能(七):依赖包管理

预期学习目标composer的学习基本composer的编写项目中composer的使用软件包管理基本配置镜像# 全局配置composer config -g repo.packagist composer https://packagist.laravel-china.org# 项目配置composer config repo.packagist composer https://packagist.laravel-china.org# 取消镜像composer config -g –unset repos.packagist # 查看配置composer config -l终端代理只在当前终端有效永久代理设置: 将代理命令写入配置文件 ~/.profile 或 ~/.bashrc 或 ~/.zshrc 中:当前终端有效: 在当前终端输入命令# Windows HTTP代理set http_proxy = http://127.0.0.1:1080set https_proxy = http://127.0.0.1:1080# Windows SOCKS5 代理set http_proxy = socks5://127.0.0.1:1080set https_proxy = socks5://127.0.0.1:1080# Windows 取消终端代理set http_proxy =set https_proxy =# Linux HTTP代理export http_proxy = http://127.0.0.1:1080export https_proxy = http://127.0.0.1:1080# Linux SOCKS5 代理export http_proxy = socks5://127.0.0.1:1080export https_proxy = socks5://127.0.0.1:1080# Linux 所有 SOCKS5 代理export ALL_PROXY = socks5://127.0.0.1:1080# Linux 取消终端代理unset http_proxyunset https_proxyunset ALL_RPOXY基本命令Composer 使用技巧与要点# 终端查看安装列表composer show# 添加拓展composer require repository/package# 删除拓展composer remove repository/package# 全局添加扩展composer global require repository/package# 全局删除拓展composer global remove repository/package问题解决requires ext-dom * -> the requested PHP extension dom is missing from your system.# 缺少 ext-dom,该拓展是用来读 取xml的,安装 php-xml 即可yum install php-xml自动加载相关文章后端相关技能(一):数据库后端相关技能(二):Vue框架后端相关技能(三):正则表达式后端相关技能(四):计算机网络后端相关技能(五):Node.js后端相关技能(六):压力测试后端相关技能(七):依赖包管理 ...

April 11, 2019 · 1 min · jiezi

composer 相关(持续更新)

常用命令解释composer install - 如有 composer.lock 文件,直接安装,否则从 composer.json 安装最新扩展包和依赖;composer update - 从 composer.json 安装最新扩展包和依赖;composer update vendor/package - 从 composer.json 或者对应包的配置,并更新到最新;composer require new/package - 添加安装 new/package, 可以指定版本,如: composer require new/package ~2.5

March 30, 2019 · 1 min · jiezi

composer failed to open stream: Operation now in progress 解决

最近遇到一个问题,一直不知道如何解决,网上搜到很多方法,都没效果 一开始以为是不支持ssl ,检查发现是支持的php -i | grep -i sslSSL => YesSSL Version => OpenSSL/1.0.2rcore SSL => supportedextended SSL => supportedopensslOpenSSL support => enabledOpenSSL Library Version => OpenSSL 1.0.2r 26 Feb 2019OpenSSL Header Version => OpenSSL 1.0.2q 20 Nov 2018Openssl default config => /usr/local/etc/openssl/openssl.cnfopenssl.cafile => /usr/local/etc/openssl/cacert.pem => /usr/local/etc/openssl/cacert.pemopenssl.capath => /usr/local/etc/openssl => /usr/local/etc/opensslSSL support => enabledOpenSSL support => enabled后来看有人说要更新ssl 秘钥wget http://curl.haxx.se/ca/cacert.pem然后在php.ini 配置curl.cainfo=/usr/local/etc/openssl/cacert.pemopenssl.cafile=/usr/local/etc/openssl/cacert.pemopenssl.capath=/usr/local/etc/openssl都没什么效果,看来并不是因为这些执行composer diagnose 之后结果composer diagnose然后逐个解决错误吧,首先是github fail 了,网上google 了下,发现需要设置一个token ,之前怎么不需要呢 ,也是奇怪,那先试试composer config –global github-oauth.github.com <token>or//在composer.json 里加入"github-oauth":{ “github.com”:"{token}" //替换成自己token}token 生成在 https://github.com/settings/t…执行composer diagnoseChecking composer.json: WARNINGrequire.illuminate/redis : unbound version constraints (*) should be avoidedChecking platform settings: OKChecking git settings: OKChecking http connectivity to packagist: OKChecking https connectivity to packagist: OKChecking github.com rate limit: OKChecking disk free space: OKChecking pubkeys:Tags Public Key Fingerprint: 57815BA2 7E54DC31 7ECC7CC5 573090D0 87719BA6 8F3BB723 4E5D42D0 84A14642Dev Public Key Fingerprint: 4AC45767 E5EC2265 2F0C1167 CBBB8A2B 0C708369 153E328C AD90147D AFE50952OKChecking composer version: OKComposer version: 1.8.4PHP version: 7.1.19PHP binary path: /usr/bin/php搞定! ...

March 26, 2019 · 1 min · jiezi

规则引擎RulerZ用法及实现原理解读

规则引擎RulerZ用法及实现原理解读废话不多说,rulerz的官方地址是:https://github.com/K-Phoen/ru…注意,本例中只拿普通数组做例子进行分析1. 简介RulerZ是一个用php实现的composer依赖包,目的是实现一个数据过滤规则引擎。RulerZ不仅支持数组过滤,也支持一些市面上常见的ORM,如Eloquent、Doctrine等,也支持Solr搜索引擎。这是一个缺少中文官方文档的开源包,当然由于star数比较少,可能作者也觉得没必要。2.安装在你的项目composer.json所在目录下运行:composer require ‘kphoen/rulerz'3.使用 - 过滤现有数组如下:$players = [ [‘pseudo’ => ‘Joe’, ‘fullname’ => ‘Joe la frite’, ‘gender’ => ‘M’, ‘points’ => 2500], [‘pseudo’ => ‘Moe’, ‘fullname’ => ‘Moe, from the bar!’, ‘gender’ => ‘M’, ‘points’ => 1230], [‘pseudo’ => ‘Alice’, ‘fullname’ => ‘Alice, from… you know.’, ‘gender’ => ‘F’, ‘points’ => 9001],];初始化引擎:use RulerZ\Compiler\Compiler;use RulerZ\Target;use RulerZ\RulerZ;// compiler$compiler = Compiler::create();// RulerZ engine$rulerz = new RulerZ( $compiler, [ new Target\Native\Native([ // 请注意,这里是添加目标编译器,处理数组类型的数据源时对应的是Native ’length’ => ‘strlen’ ]), ]);创建一条规则:$rule = “gender = :gender and points > :min_points’将参数和规则交给引擎分析。$parameters = [ ‘min_points’ => 30, ‘gender’ => ‘F’,];$result = iterator_to_array( $rulerz->filter($players, $rule, $parameters) // the parameters can be omitted if empty );// result 是一个过滤后的数组array:1 [▼ 0 => array:4 [▼ “pseudo” => “Alice” “fullname” => “Alice, from… you know.” “gender” => “F” “points” => 9001 ]]4.使用 - 判断是否满足规则$rulerz->satisfies($player, $rule, $parameters);// 返回布尔值,true表示满足5.底层代码解读下面,让我们看看从创建编译器开始,到最后出结果的过程中发生了什么。1.Compiler::create();这一步是实例化一个FileEvaluator类,这个类默认会将本地的系统临时目录当做下一步临时类文件读写所在目录,文件类里包含一个has()方法和一个write()方法。文件类如下:<?phpdeclare(strict_types=1);namespace RulerZ\Compiler;class NativeFilesystem implements Filesystem{ public function has(string $filePath): bool { return file_exists($filePath); } public function write(string $filePath, string $content): void { file_put_contents($filePath, $content, LOCK_EX); }}2.初始化RulerZ引擎,new RulerZ()先看一下RulerZ的构建方法: public function construct(Compiler $compiler, array $compilationTargets = []) { $this->compiler = $compiler; foreach ($compilationTargets as $targetCompiler) { $this->registerCompilationTarget($targetCompiler); } }这里的第一个参数,就是刚刚的编译器类,第二个是目标编译器类(实际处理数据源的),因为我们选择的是数组,所以这里的目标编译器是Native,引擎会将这个目标编译类放到自己的属性$compilationTargets。 public function registerCompilationTarget(CompilationTarget $compilationTarget): void { $this->compilationTargets[] = $compilationTarget; }3.运用filter或satisfies方法这一点便是核心了。以filter为例: public function filter($target, string $rule, array $parameters = [], array $executionContext = []) { $targetCompiler = $this->findTargetCompiler($target, CompilationTarget::MODE_FILTER); $compilationContext = $targetCompiler->createCompilationContext($target); $executor = $this->compiler->compile($rule, $targetCompiler, $compilationContext); return $executor->filter($target, $parameters, $targetCompiler->getOperators()->getOperators(), new ExecutionContext($executionContext)); }第一步会检查目标编译器是否支持筛选模式。第二步创建编译上下文,这个一般统一是Context类实例 public function createCompilationContext($target): Context { return new Context(); }第三步,执行compiler的compile()方法 public function compile(string $rule, CompilationTarget $target, Context $context): Executor { $context[‘rule_identifier’] = $this->getRuleIdentifier($target, $context, $rule); $context[’executor_classname’] = ‘Executor’.$context[‘rule_identifier’]; $context[’executor_fqcn’] = ‘\RulerZ\Compiled\Executor\Executor’.$context[‘rule_identifier’]; if (!class_exists($context[’executor_fqcn’], false)) { $compiler = function () use ($rule, $target, $context) { return $this->compileToSource($rule, $target, $context); }; $this->evaluator->evaluate($context[‘rule_identifier’], $compiler); } return new $context’executor_fqcn’; } protected function getRuleIdentifier(CompilationTarget $compilationTarget, Context $context, string $rule): string { return hash(‘crc32b’, get_class($compilationTarget).$rule.$compilationTarget->getRuleIdentifierHint($rule, $context)); } protected function compileToSource(string $rule, CompilationTarget $compilationTarget, Context $context): string { $ast = $this->parser->parse($rule); $executorModel = $compilationTarget->compile($ast, $context); $flattenedTraits = implode(PHP_EOL, array_map(function ($trait) { return “\t”.‘use \’.ltrim($trait, ‘\’).’;’; }, $executorModel->getTraits())); $extraCode = ‘’; foreach ($executorModel->getCompiledData() as $key => $value) { $extraCode .= sprintf(‘private $%s = %s;’.PHP_EOL, $key, var_export($value, true)); } $commentedRule = str_replace(PHP_EOL, PHP_EOL.’ // ‘, $rule); return <<<EXECUTORnamespace RulerZ\Compiled\Executor;use RulerZ\Executor\Executor;class {$context[’executor_classname’]} implements Executor{ $flattenedTraits $extraCode // $commentedRule protected function execute($target, array $operators, array $parameters) { return {$executorModel->getCompiledRule()}; }}EXECUTOR; }这段代码会依照crc13算法生成一个哈希串和Executor拼接作为执行器临时类的名称,并将执行器相关代码写进上文提到的临时目录中去。生成的代码如下:// /private/var/folders/w_/sh4r42wn4_b650l3pc__fh7h0000gp/T/rulerz_executor_ff2800e8<?phpnamespace RulerZ\Compiled\Executor;use RulerZ\Executor\Executor;class Executor_ff2800e8 implements Executor{ use \RulerZ\Executor\ArrayTarget\FilterTrait; use \RulerZ\Executor\ArrayTarget\SatisfiesTrait; use \RulerZ\Executor\ArrayTarget\ArgumentUnwrappingTrait; // gender = :gender and points > :min_points and points > :min_points protected function execute($target, array $operators, array $parameters) { return ($this->unwrapArgument($target[“gender”]) == $parameters[“gender”] && ($this->unwrapArgument($target[“points”]) > $parameters[“min_points”] && $this->unwrapArgument($target[“points”]) > $parameters[“min_points”])); }}这个临时类文件就是最后要执行过滤动作的类。FilterTrait中的filter方法是首先被执行的,里面会根据execute返回的布尔值来判断,是否通过迭代器返回符合条件的行。execute方法就是根据具体的参数和操作符挨个判断每行中对应的cell是否符合判断来返回true/false。 public function filter($target, array $parameters, array $operators, ExecutionContext $context) { return IteratorTools::fromGenerator(function () use ($target, $parameters, $operators) { foreach ($target as $row) { $targetRow = is_array($row) ? $row : new ObjectContext($row); if ($this->execute($targetRow, $operators, $parameters)) { yield $row; } } }); }satisfies和filter基本逻辑类似,只是最后satisfies是执行单条判断。有一个问题,我们的编译器是如何知道我们设立的操作规则$rule的具体含义的,如何parse的?这就涉及另一个问题了,抽象语法树(AST)。Go further - 抽象语法树我们都知道php zend引擎在解读代码的过程中有一个过程是语法和词法分析,这个过程叫做parser,中间会将代码转化为抽象语法树,这是引擎能够读懂代码的关键步骤。同样,我们在写一条规则字符串的时候,代码如何能够明白我们写的是什么呢?那就是抽象语法树。以上面的规则为例:gender = :gender and points > :min_points这里, =、and、>都是操作符,但是机器并不知道他们是操作符,也不知道其他字段是什么含义。于是rulerz使用自己的语法模板。首先是默认定义了几个操作符。<?phpdeclare(strict_types=1);namespace RulerZ\Target\Native;use RulerZ\Target\Operators\Definitions;class NativeOperators{ public static function create(Definitions $customOperators): Definitions { $defaultInlineOperators = [ ‘and’ => function ($a, $b) { return sprintf(’(%s && %s)’, $a, $b); }, ‘or’ => function ($a, $b) { return sprintf(’(%s || %s)’, $a, $b); }, ’not’ => function ($a) { return sprintf(’!(%s)’, $a); }, ‘=’ => function ($a, $b) { return sprintf(’%s == %s’, $a, $b); }, ‘is’ => function ($a, $b) { return sprintf(’%s === %s’, $a, $b); }, ‘!=’ => function ($a, $b) { return sprintf(’%s != %s’, $a, $b); }, ‘>’ => function ($a, $b) { return sprintf(’%s > %s’, $a, $b); }, ‘>=’ => function ($a, $b) { return sprintf(’%s >= %s’, $a, $b); }, ‘<’ => function ($a, $b) { return sprintf(’%s < %s’, $a, $b); }, ‘<=’ => function ($a, $b) { return sprintf(’%s <= %s’, $a, $b); }, ‘in’ => function ($a, $b) { return sprintf(‘in_array(%s, %s)’, $a, $b); }, ]; $defaultOperators = [ ‘sum’ => function () { return array_sum(func_get_args()); }, ]; $definitions = new Definitions($defaultOperators, $defaultInlineOperators); return $definitions->mergeWith($customOperators); }}在RulerZParserParser中,有如下方法:public function parse($rule){ if ($this->parser === null) { $this->parser = Compiler\Llk::load( new File\Read(DIR.’/../Grammar.pp’) ); } $this->nextParameterIndex = 0; return $this->visit($this->parser->parse($rule));}这里要解读一个核心语法文件://// Hoa////// @license//// New BSD License//// Copyright © 2007-2015, Ivan Enderlin. All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are met:// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above copyright// notice, this list of conditions and the following disclaimer in the// documentation and/or other materials provided with the distribution.// * Neither the name of the Hoa nor the names of its contributors may be// used to endorse or promote products derived from this software without// specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE// POSSIBILITY OF SUCH DAMAGE.//// Inspired from \Hoa\Ruler\Grammar.//// @author Stéphane Py <stephane.py@hoa-project.net>// @author Ivan Enderlin <ivan.enderlin@hoa-project.net>// @author Kévin Gomez <contact@kevingomez.fr>// @copyright Copyright © 2007-2015 Stéphane Py, Ivan Enderlin, Kévin Gomez.// @license New BSD License%skip space \s// Scalars.%token true (?i)true%token false (?i)false%token null (?i)null// Logical operators%token not (?i)not\b%token and (?i)and\b%token or (?i)or\b%token xor (?i)xor\b// Value%token string ("|’)(.?)(?<!\)\1%token float -?\d+.\d+%token integer -?\d+%token parenthesis_ (%token parenthesis )%token bracket [%token bracket ]%token comma ,%token dot .%token positional_parameter ?%token named_parameter :[a-z-A-Z0-9]+%token identifier [^\s()[],.]+#expression: logical_operation()logical_operation: operation() ( ( ::and:: #and | ::or:: #or | ::xor:: #xor ) logical_operation() )?operation: operand() ( <identifier> logical_operation() #operation )?operand: ::parenthesis_:: logical_operation() ::parenthesis:: | value()parameter: <positional_parameter> | <named_parameter>value: ::not:: logical_operation() #not | <true> | <false> | <null> | <float> | <integer> | <string> | parameter() | variable() | array_declaration() | function_call()variable: <identifier> ( object_access() #variable_access )*object_access: ::dot:: <identifier> #attribute_access#array_declaration: ::bracket:: value() ( ::comma:: value() ) ::bracket::#function_call: <identifier> ::parenthesis:: ( logical_operation() ( ::comma:: logical_operation() )* )? ::parenthesis::上面Llk::load方法会加载这个基础语法内容并解析出片段tokens,tokens解析的逻辑就是正则匹配出我们需要的一些操作符和基础标识符,并将对应的正则表达式提取出来:array:1 [▼ “default” => array:20 [▼ “skip” => “\s” “true” => “(?i)true” “false” => “(?i)false” “null” => “(?i)null” “not” => “(?i)not\b” “and” => “(?i)and\b” “or” => “(?i)or\b” “xor” => “(?i)xor\b” “string” => “("|’)(.*?)(?<!\)\1” “float” => “-?\d+.\d+” “integer” => “-?\d+” “parenthesis” => “(” “parenthesis” => “)” “bracket” => “[” “bracket” => “]” “comma” => “,” “dot” => “.” “positional_parameter” => “?” “named_parameter” => “:[a-z-A-Z0-9]+” “identifier” => “[^\s()[],.]+” ]]这一步也会生成一个rawRulesarray:10 [▼ “#expression” => " logical_operation()” “logical_operation” => " operation() ( ( ::and:: #and | ::or:: #or | ::xor:: #xor ) logical_operation() )?" “operation” => " operand() ( <identifier> logical_operation() #operation )?" “operand” => " ::parenthesis_:: logical_operation() ::parenthesis:: | value()" “parameter” => " <positional_parameter> | <named_parameter>" “value” => " ::not:: logical_operation() #not | <true> | <false> | <null> | <float> | <integer> | <string> | parameter() | variable() | array_declaration() | function_call( ▶" “variable” => " <identifier> ( object_access() #variable_access )*" “object_access” => " ::dot:: <identifier> #attribute_access" “#array_declaration” => " ::bracket:: value() ( ::comma:: value() )* ::bracket::" “#function_call” => " <identifier> ::parenthesis:: ( logical_operation() ( ::comma:: logical_operation() )* )? ::_parenthesis::"]这个rawRules会通过analyzer类的analyzeRules方法解析替换里面的::表示的空位,根据$_ppLexemes属性的值,Compiler\Llk\Lexer()词法解析器会将rawRules数组每一个元素解析放入双向链表栈(SplStack)中,然后再通过对该栈插入和删除操作,形成一个包含所有操作符和token实例的数组$rules。array:54 [▼ 0 => Concatenation {#64 ▶} “expression” => Concatenation {#65 ▼ #_name: “expression” #_children: array:1 [▼ 0 => 0 ] #_nodeId: “#expression” #_nodeOptions: [] #_defaultId: “#expression” #_defaultOptions: [] #_pp: " logical_operation()" #_transitional: false } 2 => Token {#62 ▶} 3 => Concatenation {#63 ▼ #_name: 3 #_children: array:1 [▼ 0 => 2 ] #_nodeId: “#and” #_nodeOptions: [] #_defaultId: null #_defaultOptions: [] #_pp: null #_transitional: true } 4 => Token {#68 ▶} 5 => Concatenation {#69 ▶} 6 => Token {#70 ▶} 7 => Concatenation {#71 ▶} 8 => Choice {#72 ▶} 9 => Concatenation {#73 ▶} 10 => Repetition {#74 ▶} “logical_operation” => Concatenation {#75 ▶} 12 => Token {#66 ▶} 13 => Concatenation {#67 ▶} 14 => Repetition {#78 ▶} “operation” => Concatenation {#79 ▶} 16 => Token {#76 ▶} 17 => Token {#77 ▶} 18 => Concatenation {#82 ▶} “operand” => Choice {#83 ▶} 20 => Token {#80 ▶} 21 => Token {#81 ▼ #_tokenName: “named_parameter” #_namespace: null #_regex: null #_ast: null #_value: null #_kept: true #_unification: -1 #_name: 21 #_children: null #_nodeId: null #_nodeOptions: [] #_defaultId: null #_defaultOptions: [] #_pp: null #_transitional: true } “parameter” => Choice {#86 ▶} 23 => Token {#84 ▶} 24 => Concatenation {#85 ▶} 25 => Token {#89 ▶} 26 => Token {#90 ▶} 27 => Token {#91 ▶} 28 => Token {#92 ▶} 29 => Token {#93 ▶} 30 => Token {#94 ▶} “value” => Choice {#95 ▶} 32 => Token {#87 ▶} 33 => Concatenation {#88 ▶} 34 => Repetition {#98 ▶} “variable” => Concatenation {#99 ▶} 36 => Token {#96 ▶} 37 => Token {#97 ▶} “object_access” => Concatenation {#102 ▶} 39 => Token {#100 ▶} 40 => Token {#101 ▶} 41 => Concatenation {#105 ▶} 42 => Repetition {#106 ▶} 43 => Token {#107 ▶} “array_declaration” => Concatenation {#108 ▶} 45 => Token {#103 ▶} 46 => Token {#104 ▶} 47 => Token {#111 ▶} 48 => Concatenation {#112 ▶} 49 => Repetition {#113 ▶} 50 => Concatenation {#114 ▶} 51 => Repetition {#115 ▶} 52 => Token {#116 ▶} “function_call” => Concatenation {#117 ▶}]然后返回HoaCompilerLlkParser实例,这个实例有一个parse方法,正是此方法构成了一个语法树。public function parse($text, $rule = null, $tree = true) { $k = 1024; if (isset($this->_pragmas[‘parser.lookahead’])) { $k = max(0, intval($this->_pragmas[‘parser.lookahead’])); } $lexer = new Lexer($this->_pragmas); $this->_tokenSequence = new Iterator\Buffer( $lexer->lexMe($text, $this->_tokens), $k ); $this->_tokenSequence->rewind(); $this->_errorToken = null; $this->_trace = []; $this->_todo = []; if (false === array_key_exists($rule, $this->_rules)) { $rule = $this->getRootRule(); } $closeRule = new Rule\Ekzit($rule, 0); $openRule = new Rule\Entry($rule, 0, [$closeRule]); $this->_todo = [$closeRule, $openRule]; do { $out = $this->unfold(); if (null !== $out && ‘EOF’ === $this->_tokenSequence->current()[’token’]) { break; } if (false === $this->backtrack()) { $token = $this->_errorToken; if (null === $this->_errorToken) { $token = $this->_tokenSequence->current(); } $offset = $token[‘offset’]; $line = 1; $column = 1; if (!empty($text)) { if (0 === $offset) { $leftnl = 0; } else { $leftnl = strrpos($text, “\n”, -(strlen($text) - $offset) - 1) ?: 0; } $rightnl = strpos($text, “\n”, $offset); $line = substr_count($text, “\n”, 0, $leftnl + 1) + 1; $column = $offset - $leftnl + (0 === $leftnl); if (false !== $rightnl) { $text = trim(substr($text, $leftnl, $rightnl - $leftnl), “\n”); } } throw new Compiler\Exception\UnexpectedToken( ‘Unexpected token “%s” (%s) at line %d and column %d:’ . “\n” . ‘%s’ . “\n” . str_repeat(’ ‘, $column - 1) . ‘↑’, 0, [ $token[‘value’], $token[’token’], $line, $column, $text ], $line, $column ); } } while (true); if (false === $tree) { return true; } $tree = $this->_buildTree(); if (!($tree instanceof TreeNode)) { throw new Compiler\Exception( ‘Parsing error: cannot build AST, the trace is corrupted.’, 1 ); } return $this->_tree = $tree; }我们得到的一个完整的语法树是这样的:Rule {#120 ▼ #_root: Operator {#414 ▼ #_name: “and” #_arguments: array:2 [▼ 0 => Operator {#398 ▼ #_name: “=” #_arguments: array:2 [▼ 0 => Context {#396 ▼ #_id: “gender” #_dimensions: [] } 1 => Parameter {#397 ▼ -name: “gender” } ] #_function: false #_laziness: false #_id: null #_dimensions: [] } 1 => Operator {#413 ▼ #_name: “and” #_arguments: array:2 [▼ 0 => Operator {#401 ▼ #_name: “>” #_arguments: array:2 [▼ 0 => Context {#399 ▶} 1 => Parameter {#400 ▶} ] #_function: false #_laziness: false #_id: null #_dimensions: [] } 1 => Operator {#412 ▶} ] #_function: false #_laziness: true #_id: null #_dimensions: [] } ] #_function: false #_laziness: true #_id: null #_dimensions: [] }}这里有根节点、子节点、操作符参数以及HoaRulerModelOperator实例。这时$executorModel = $compilationTarget->compile($ast, $context);就可以通过NativeVisitor的visit方法对这个语法树进行访问和分析了。这一步走的是visitOperator() /** * {@inheritdoc} */ public function visitOperator(AST\Operator $element, &$handle = null, $eldnah = null) { $operatorName = $element->getName(); // the operator does not exist at all, throw an error before doing anything else. if (!$this->operators->hasInlineOperator($operatorName) && !$this->operators->hasOperator($operatorName)) { throw new OperatorNotFoundException($operatorName, sprintf(‘Operator “%s” does not exist.’, $operatorName)); } // expand the arguments $arguments = array_map(function ($argument) use (&$handle, $eldnah) { return $argument->accept($this, $handle, $eldnah); }, $element->getArguments()); // and either inline the operator call if ($this->operators->hasInlineOperator($operatorName)) { $callable = $this->operators->getInlineOperator($operatorName); return call_user_func_array($callable, $arguments); } $inlinedArguments = empty($arguments) ? ’’ : ‘, ‘.implode(’, ‘, $arguments); // or defer it. return sprintf(‘call_user_func($operators["%s"]%s)’, $operatorName, $inlinedArguments); }返回的逻辑代码可以通过得到:$executorModel->getCompiledRule() ...

March 4, 2019 · 10 min · jiezi

超级方便好用的微信公众号菜单管理扩展

看了 FastAdmin 中有一个微信管理插件,就萌生了自己做一个的想法。展示DEMOhttp://wechat-menu.lzis.me素材选择菜单设置菜单事件处理配置其他事件处理配置,比如收到文本消息、订阅、取消订阅等安装$ composer require largezhou/wechat-menu -vvv详细使用方法https://github.com/largezhou/…重点[????????????]觉得有用的话,不要吝啬你的 Star⭐ 呀。

January 29, 2019 · 1 min · jiezi

php无限分类树扩展组件

PHP系统树图github地址dendrogram Laravel PHP v1.0 5.* >=5.6.4 安装composer require dendrogram/dendrogram:v1.0配置首先往Laravel应用中注册ServiceProvider,打开文件config/app.php,在providers中添加一项:‘providers’ => [ DenDroGram\DendrogramServiceProvider::class ]然后发布拓展包的配置文件,使用如下命令:php artisan vendor:publish此时config目录下会生成dendrogram.php配置文件数据导入(两表三个自定义函数)php artisan migrateadjacency结构 以父节点为基准的链式查询 增删容易 查询不便nested结构 以左右值包容形式 增删不便 查询容易图片描述方法说明调用 构造参数 方法说明 方法参数 返回 备注 (new DenDroGram(AdjacencyList::class))->buildTree($node_id,[’name’]) adjacency数据格式 adjacency格式数据生成目录式结构树 根节点id , 每个节点显示信息 返回html文本string 视图的相关在dendrogram.php中配置 如操作节点方法的路由 (new DenDroGram(AdjacencyList::class))->operateNode($action,$data) adjacency数据格式 adjacency格式数据的节点操作 action增删改标识 , data节点详情数据 返回boolean 注意视图与之对应的数据结构AdjacencyList::class (new DenDroGram(AdjacencyList::class))->getTreeData($node_id); adjacency数据格式 adjacency数据构造成多维数组 根节点id 返回array 多维数组结构 (new DenDroGram(NestedSet::class))->buildTree($node_id,[’name’]) NestedSet数据格式 NestedSet格式数据生成根茎式结构树 根节点id , 每个节点显示信息 返回html文本string 视图的相关在dendrogram.php中配置 如操作节点方法的路由 (new DenDroGram(NestedSet::class))->operateNode($action,$data) NestedSet数据格式 NestedSet格式数据的节点操作 action增删改标识 , data节点详情数据 返回boolean 注意视图与之对应的数据结构NestedSet::class (new DenDroGram(NestedSet::class))->getTreeData($node_id); NestedSet数据格式 NestedSet数据构造成多维数组 根节点id 返回array 多维数组结构 举个栗子adjacency数据结构生成的视图图片描述nested数据结构生成的视图 ...

January 28, 2019 · 1 min · jiezi

PHP程序员如何优雅的搬砖

我一生的文章都会放在这里,我的博客,我希望每一行代码,每一段文字都能帮助你。https://github.com/CrazyCodes…前言Hello , 各位Coder !在这里向各位工程师提前拜年 “新年快乐” , 距离年三十已经没有几天了,可能有些朋友还坚持在一线战斗着,有些已经回到家乡陪伴家人。北京每到这个时候都似一座空城,城与城之间表现的那么凄凉。这是年前的最后一篇文章,本章来聊一聊程序员如何优雅的搬砖搬砖既 “为达到目的,不断重复某项工作的行为,其实与造轮子一次也不谋而同”基础这里的基础并非单指其技术能力,技术底蕴,更有意体现程序员在初期不断重复的工作而获得的感想与意识。想必大家都是这么过来的,第一年时根据需求不断创新,不断磨练。所有的功能都必须自己写,用其他人的不放心。但自己写的东西经常出问题,无论是思路或者代码都不够精炼。一层一层的技术债在完工后不断的涌现出来。当时你会不会有跑路的想法?选择在不断的进步中,我们积攒了很多经验,这里指的变是开发经验,并非什么技术经验。开发经验大概意思是在看到某项需求时,可以快速的根据自己的知识与经验的储备选择其开发框架、语言、数据库及流程逻辑等。这里就是在做选择,你会对该需求给出自己的几项方案,而不是现查现写。开源开源的目的是什么?建立一个更好的技术生态圈,Coder与Coder之间互相帮助,达到更好的效果(并不是结对编程哈),现如今PHP的生态圈非常健康的运转,无论是PHP7的发布或者Composer的诞生,都为贵圈提供了更好的技术与实践的支持。我们应更好的去接触、熟练的去运用各位大神费尽心血为我们准备的全新的PHP本机讲过很多初学者在本地开发时,对本地的开发环境毫无关心,随随便便拿一个集成开发工具便搭建了一整套的运行环境,对其本质毫无理解,我想大部分人都有过“全干工程师”的历程,对本地环境毫无在意的程序员,敢说在生产、测试环境中依旧无法出色的表现其技术能力。建议在这里,我给出一些常见业务需求的解决方案 (并非是一些高级的东西)后台如果是从头做一个后台,然而又不想从0开始搭建后台的逻辑,在这里我强烈推荐laravel-admin,laravel虽然性能方面低于其他框架,但其作为后台的开发框架来说我认为还是第一名的。https://laravel.com/https://laravel-admin.org/https://laravel-admin.org/doc…laravel-admin 安装比其他的开源程序要简单的多,这都寄托于能力极佳的composer与laravelcomposer require encore/laravel-admin接口接口开发着重性能,相应速度,如果依旧喜欢laravel,可以选择lumenhttps://lumen.laravel.com/或者使用C编写的框架 Phalconhttps://phalconphp.com/zh/实在感觉这些框架太过庞大,复杂也可以选择 Slim ,他一定精简到让你飞起http://www.slimframework.com/不想使用框架?但从0写还嫌麻烦,这时你可以考虑 鸟哥的Yaf 或者 韩天峰的 Swoolehttps://www.swoole.co.uk/http://php.net/manual/en/book…其他熟练去搜集、查找适合自己业务的包,熟练去运用其优势。让自己不需要再重复造轮子,无止尽的还技术债,这才是2019年程序员应该学习的。https://segmentfault.com/a/11…https://segmentfault.com/a/11...https://packagist.org/https://github.com/致谢感谢你看到这里,希望本篇文章可以帮助到你,谢谢。

January 28, 2019 · 1 min · jiezi

使用composer安装composer包时提示需要输入授权码,但是当输入授权码后,提示授权码输入成功但是提示安装失败解决

这两天我一直在解决一个问题,一直都解决不了,差点就要被逼疯了,今天终于解决了,下面记录下解决方法,那么这是一个什么样的问题呢?问题描述:我使用composer安装composer包,总是提示需要授权码,要授权码也无所谓啦,对吧!但是当我输入授权码之后就报错了,然后在网上搜索,网上一大片的都是关于如何获取授权码相关的内容,都没有实际的解决我的问题,授权码获取很简单的只需要访问github的设置页面:https://github.com/settings/d… 然后选择开发者设置中的个人访问令牌,然后你就可以得到一个授权码了,如果可以直接输入授权码解决的话,我早就解决了,都不需要这么的麻烦了。如下是我正常操作下的问题示意图:解决:经过两天的折腾,终于解决了上面的问题:1:修改composer.json文件将comspoer.sjon文件中的config配置项修改为:“config”: { “process-timeout”: 1800, “fxp-asset”: { “repositories”: { “bower-asset/eve”: { “type”: “bower-vcs”, “url”: “https://github.com/adobe-webplatform/eve.git" } } } },2:修改完成之后再进行安装composer包,这时候就安装成功了终于解决了!!!!参考:https://juejin.im/post/5a9533…

January 14, 2019 · 1 min · jiezi

如何发布自己的composer包

前提:你需要收github和Packagist账号github地址:https://github.comPackagist地址:https://packagist.org一:将你的composer包代码上传到github上如何上传代码到github上可以参考我的:github 简单使用如果你需要可以实现composer下载,那么你的composer包中必须要有composer.json文件composer.json文件基本格式你可以按照如下格式编写:{ “name”: “huaweichenai/baidu-discern”, “description”: “Baidu realizes picture recognition text package(百度实现图片识别文字包)”, “keywords”: [“yii2”,“baidu”,“discern”,“extension”], “type”: “yii2-extension”, “license”: “BSD-3-Clause”, “authors”: [ { “name”: “huaweichenai”, “email”: “243681093@qq.com”, “homepage”: “https://www.wj0511.com/” } ], “require”: {}, “minimum-stability”: “dev”, “autoload”: { “psr-4”: { “huaweichenai\discern\”: “src” } }}二:将composer包上传到packagist1:登录packagist然后点击右上角的submit按钮2:在输入框中输入你的github代码仓库地址,然后点击check如果出现错误根据错误提示解决,没有错误点击submit等到submit执行过后出现如下界面表示你的composer包已经上传packagist上了虽然我们已经将comspoer包上传到packagist上了,但是我们在本地安装我们的composer包时还是会报错的这是因为我们没有在github上指定版本的原因,如果我们不想在github上指定版本,这时候我们可以执行composer require huaweichenai/baidu-discern “dev-master” #huaweichenai/baidu-discern是我的composer包这时候就可以将我们的composer包下载下来了我们也可以在github上指定版本,那么如何在github上指定版本呢?1:点击releases2:点击Create a new release3:发布一个版本4:发布一个版本之后我们在packgist上点击update进行更新,这时候我们就可以在本地不进行指定版本安装了composer require huaweichenai/baidu-discern将发布包上传到 Packagist 后可能需要几分钟才可以使用,如果出现问题,等过几分钟在进行安装就可以了

January 11, 2019 · 1 min · jiezi

composer安装composer包报Your requirements could not be resolved

一:使用composer安装composer包时遇到Your requirements could not be resolved to an installable set of packages分析:这是由于doctrine/instantiator的1.1.0版本必须是PHP7.1,然而我的PHP环境是PHP7.0.12,但是我发现一个问题,我的composer.json文件内没有doctrine/instantiator包信息,那么为什么回报这样一个错误呢?这时候我找到vendor/doctrine/instantiator发现doctrine/instantiator包已经安装在我的框架中了,打开vendor/doctrine/instantiator目录下的composer.json文件发现,这个包所需要的环境是PHP7.1:找到doctrine/instantiator包的地址:https://packagist.org/package…这时候发现doctrine/instantiator的1.1.0版本所需的PHP环境为7.1,所以我想是不是由于我的框架中的doctrine/instantiator包的版本是1.1.0导致在这个框架中安装composer包失败的呢?解决:1:将doctrine/instantiator包的版本变为我们需要的版本(这里我将doctrine/instantiator包的版本变为1.0.x-dev)composer require doctrine/instantiator “1.0.x-dev"2:将doctrine/instantiator包变为所需要的版本后再安装你需要的composer包,这时候就不会报错误了(这里我以huaweichenai/baidu-discern包为例)这是使用composer安装就成功了网上有一种方法:使用 composer install –ignore-platform-reqs 命令设置忽略版本匹配然后再进行安装你所需要的composer包,这种方法我进行测试后发现还是报错,具体为什么就不清楚了,有知道为什么的欢迎留言告诉博主

January 10, 2019 · 1 min · jiezi

Composer简易教程

Composer简易教程1. composer安装参考官方教程:https://docs.phpcomposer.com/00-intro.html2. composer安装第三方包1. 命令行安装:composer require “curl/curl"2. 编辑composer.json文件安装:{ “name”: “test/test”, “description”: “”, “license”: “MIT”, “authors”: [ { “name”: “a”, “email”: “a@gmail.com” } ], “require”: { “php”: “>=7.2.0”, “curl/curl”: “^1.6” //这是需要安装的包 } “config”: { // 不要.git文件夹 “preferred-install”: “dist” }}执行composer install/update安装3. 自己制作composer安装包1. 创建包自己在github/gitlab上创建了一个项目地址是:https://github.com/test/test此项目的compoesr.json文件中需要定义名字,详细内容如下:{ // 注意,这里定义的名字,和之后被require的时候用到的名字相同,而不是github url的后缀 “name”: “test1/test1”, “authors”: [ { “name”: “a”, “email”: “a@gmail.com” } ], “config”: { “preferred-install”: “dist”, “sort-packages”: true, “optimize-autoloader”: true, “secure-http”: false }}2. require该包在需要使用该包的项目中创建composer.json,内容如下:{ “name”: “aaa/bbb”, “authors”: [ { “name”: “a”, “email”: “a@gmail.com” } ], “require”: { “test1/test1”: “dev-master” }, “repositories”: [ { “type”: “vcs”, // 这个地址填该项目的连接地址 “url”: “https://github.com/test/test” } ], “config”: { “preferred-install”: “dist”, “sort-packages”: true, “optimize-autoloader”: true, “secure-http”: false }}3. 安装该包执行composer install就可以安装自己的包了,而不是从packagist上安装4. 自己搭建composer仓库5. install和update的区别两者都可以安装包,区别有:install会读取composer.lock文件,根据缓存的指定版本进行安装,如果没有,则会在安装完毕后创建;update不会读取composer.lock文件,而是升级某个包或者所有包,并更新composer.lock文件所以对于生产环境,推荐使用composer install ...

January 9, 2019 · 1 min · jiezi

wamp环境下运行composer的坑

今天在用composer安装laravel时报错The openssl extension is required for SSL/TLS protection but is not availab le. If you can not enable the openssl extension, you can disable this error , at your own risk, by setting the ‘disable-tls’ option to true.网上说是OpenSSL没有打开的问题,打开php.ini,启用插件并设置相应的证书,然后重启Apache。理论上来说,走到这一步应该没什么问题了,phpinfo();里也有OpenSSL的扩展,但是报错依旧。研究后发现,composer判断OpenSSL的依据是:当前环境变量下的php目录下的php.ini文件,但是wamp下php.ini文件实际上对应的是php目录下的phpForApache.ini而不是php.ini,所以把phpForApache.ini里的内容全部复制到php.ini,再次运行composer install就没有报错了。

January 7, 2019 · 1 min · jiezi