├── .gitignore ├── README.md ├── composer.json ├── src ├── Packagist.php └── Service │ ├── BaiduTranslate.php │ └── YoudaoTranslate.php ├── test.php └── tests └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 简介 2 | 3 | > Laravel 另一个令人喜欢的地方,是拥有活跃的开发者社区,而活跃的开发者社区带来的,是繁华的扩展包生态 ———— @Summer 4 | 5 | 该项目统计了目前 [packagist](https://packagist.org/) 下载量最高的 50 个 `Laravel` 扩展包。并把更新脚本放到了[github](https://github.com/godruoyi/laravel-package-top)。 6 | 7 | [项目地址 https://github.com/godruoyi/laravel-package-top](https://github.com/godruoyi/laravel-package-top) 8 | 9 | ## 更新 10 | 11 | 我们将 `每个月` 更新一次脚本,也方便我们及时的查看目前最流行的的 `laravel package`。 12 | 13 | > 你可以 `clone` 该项目,运行根目录下的 `test.php` 来同步更新。还可以自定义排序规则、搜索关键字等。记得 `star` 哟!! :smile: 14 | 15 | 相信下面这些扩展包会让你的编码更加高效。 16 | 17 | - 新增 [有道云翻译](http://api.fanyi.baidu.com/api/trans/product/index) 接口支持,把拉取到的 `laravel package` 包介绍信息自动翻译为中文。 18 | 19 | ## 排名(下载量) 20 | 21 | > 中文翻译来自 有道云翻译 接口,可能和实际有所区别。 22 | 23 | | 排名 | 包地址 | 下载次数 | Star | 描述 | 24 | |---|---|---|---|---| 25 | | 1 | [intervention/image](https://github.com/Intervention/image) | 10269953 | 6538 | 最流行、完善的图片操作库 | 26 | | 2 | [barryvdh/laravel-debugbar](https://github.com/barryvdh/laravel-debugbar) | 7251826 | 6594 | 开发调试必备神器 | 27 | | 3 | [barryvdh/laravel-ide-helper](https://github.com/barryvdh/laravel-ide-helper) | 7081013 | 6108 | Laravel IDE助手,为所有Facade类生成正确的PHPDocs,以改进 autoload。 | 28 | | 4 | [maatwebsite/excel](https://github.com/Maatwebsite/Laravel-Excel) | 5552357 | 4412 | 基于 PHPExcel,在 Laravel 中导入和导出 Excel 和 CSV 的一种很有说服力的方法。 | 29 | | 5 | [aws/aws-sdk-php-laravel](https://github.com/aws/aws-sdk-php-laravel) | 2954963 | 940 | 一个简单的 Laravel 5服务提供商,包括用于PHP的AWS SDK。 | 30 | | 6 | [jenssegers/agent](https://github.com/jenssegers/agent) | 2903311 | 1874 | 支持 Laravel的桌面/移动用户代理解析器,基于 mobile 检测。 | 31 | | 7 | [barryvdh/laravel-cors](https://github.com/barryvdh/laravel-cors) | 2742897 | 2324 | 在您的Laravel应用程序中添加 CORS (跨源资源共享)头支持。 | 32 | | 8 | [tymon/jwt-auth](https://github.com/tymondesigns/jwt-auth) | 2654902 | 5470 | 用于 Laravel 和Lumen的JSON Web Token认证。 | 33 | | 9 | [bugsnag/bugsnag-laravel](https://github.com/bugsnag/bugsnag-laravel) | 2430971 | 347 | 关于 Laravel 应用程序的官方提示。 | 34 | | 10 | [barryvdh/laravel-dompdf](https://github.com/barryvdh/laravel-dompdf) | 2167237 | 1819 | A DOMPDF Wrapper for Laravel | 35 | | 11 | [maknz/slack](https://github.com/maknz/slack) | 2051398 | 983 | 一个简单的PHP包,用于将消息发送到Slack,重点放在易用性和优雅的语法上。 | 36 | | 12 | [zizaco/entrust](https://github.com/Zizaco/entrust) | 1827118 | 5505 | 这个包提供了一种灵活的方式,可以将基于角色的权限添加到Laravel。 | 37 | | 13 | [yajra/laravel-datatables-oracle](https://github.com/yajra/laravel-datatables) | 1697566 | 1878 | Laravel 4|5的jQuery DataTables API。 | 38 | | 14 | [way/generators](https://github.com/JeffreyWay/Laravel-4-Generators) | 1591561 | 3160 | 快速生成资源、迁移、模型等等。 | 39 | | 15 | [sentry/sentry-laravel](https://github.com/getsentry/sentry-laravel) | 1438746 | 192 | 用于 Sentry 的Laravel集成(https://sentry.io) | 40 | | 16 | [dingo/api](https://github.com/dingo/api) | 1401773 | 7116 | 一个用于Laravel和Lumen框架的RESTful API包。 | 41 | | 17 | [anahkiasen/underscore-php](https://github.com/Anahkiasen/underscore-php) | 1268007 | 793 | A redacted PHP port of Underscore.js with additional functions and goodies | 42 | | 18 | [jenssegers/date](https://github.com/jenssegers/date) | 1212993 | 1124 | 基于 Carbon 的时间库,可帮助您使用多种语言的日期。 | 43 | | 19 | [jenssegers/mongodb](https://github.com/jenssegers/laravel-mongodb) | 1168814 | 3100 | 基于MongoDB的Laravel模型和查询生成器(Moloquent) | 44 | | 20 | [cviebrock/eloquent-sluggable](https://github.com/cviebrock/eloquent-sluggable) | 1139748 | 1848 | 轻松地为你在Laravel 5的有说服力的模型制作鼻涕虫。 | 45 | | 21 | [lucadegasperi/oauth2-server-laravel](https://github.com/lucadegasperi/oauth2-server-laravel) | 1115820 | 2193 | 为Laravel和Lumen的OAuth 2.0桥。 | 46 | | 22 | [davejamesmiller/laravel-breadcrumbs](https://github.com/davejamesmiller/laravel-breadcrumbs) | 1051250 | 1266 | 这是一种简单的拉威尔式的制作面包屑的方法。 | 47 | | 23 | [laracasts/utilities](https://github.com/laracasts/PHP-Vars-To-Js-Transformer) | 1007572 | 1555 | 将PHP转换为JavaScript。 | 48 | | 24 | [laracasts/generators](https://github.com/laracasts/Laravel-5-Generators-Extended) | 1007179 | 1720 | 延长Laravel 5的发电机。 | 49 | | 25 | [barryvdh/laravel-snappy](https://github.com/barryvdh/laravel-snappy) | 992571 | 875 | Snappy PDF/图片为Laravel 4。 | 50 | | 26 | [itsgoingd/clockwork](https://github.com/itsgoingd/clockwork) | 964481 | 1636 | php开发工具集成到您的浏览器。 | 51 | | 27 | [rap2hpoutre/laravel-log-viewer](https://github.com/rap2hpoutre/laravel-log-viewer) | 922081 | 1456 | Laravel日志的读者 | 52 | | 28 | [roumen/sitemap](https://github.com/Laravelium/laravel-sitemap) | 914220 | 951 | 对于Laravel来说,一个不那么简单的sitemap生成器。 | 53 | | 29 | [intervention/imagecache](https://github.com/Intervention/imagecache) | 860070 | 348 | 对干预图像类进行缓存扩展。 | 54 | | 30 | [laravelbook/ardent](https://github.com/laravel-ardent/ardent) | 834194 | 1316 | 为Laravel 5的雄辩的ORM验证智能模型。 | 55 | | 31 | [pragmarx/google2fa](https://github.com/antonioribeiro/google2fa) | 830465 | 750 | 一个一次性密码认证包,兼容谷歌认证器。 | 56 | | 32 | [rcrowe/twigbridge](https://github.com/rcrowe/TwigBridge) | 709363 | 704 | 将小树枝的力量添加到拉勒维尔。 | 57 | | 33 | [venturecraft/revisionable](https://github.com/VentureCraft/revisionable) | 702487 | 1479 | 为您的模型保留修订历史,而不需要考虑,创建为一个与Laravel一起使用的包。 | 58 | | 34 | [propaganistas/laravel-phone](https://github.com/Propaganistas/Laravel-Phone) | 701480 | 623 | 根据谷歌的libphonenumber API将电话号码功能添加到Laravel和Lumen。 | 59 | | 35 | [prettus/l5-repository](https://github.com/andersao/l5-repository) | 680490 | 2285 | Laravel 5 -存储库到数据库层。 | 60 | | 36 | [simplesoftwareio/simple-qrcode](https://github.com/SimpleSoftwareIO/simple-qrcode) | 666474 | 627 | 简单的QrCode是为Laravel制作的二维码生成器。 | 61 | | 37 | [mews/purifier](https://github.com/mewebstudio/Purifier) | 638763 | 732 | Laravel 5 HtmlPurifier包 | 62 | | 38 | [prettus/laravel-validation](https://github.com/andersao/laravel-validator) | 634883 | 166 | Laravel验证服务 | 63 | | 39 | [spatie/laravel-fractal](https://github.com/spatie/laravel-fractal) | 625196 | 939 | 对于Laravel应用来说,易于使用分形集成。 | 64 | | 40 | [laracasts/testdummy](https://github.com/laracasts/TestDummy) | 614392 | 448 | 简单测试存根 | 65 | | 41 | [torann/geoip](https://github.com/Torann/laravel-geoip) | 567209 | 644 | 支持多个GeoIP服务。 | 66 | | 42 | [jenssegers/rollbar](https://github.com/jenssegers/laravel-rollbar) | 559199 | 326 | 用于Laravel项目的Rollbar错误监视集成。 | 67 | | 43 | [spatie/laravel-permission](https://github.com/spatie/laravel-permission) | 553829 | 2842 | 对Laravel 5.4和up的权限处理。 | 68 | | 44 | [xethron/migrations-generator](https://github.com/Xethron/migrations-generator) | 551829 | 1760 | 从现有数据库生成Laravel迁移。 | 69 | | 45 | [mcamara/laravel-localization](https://github.com/mcamara/laravel-localization) | 546214 | 1567 | 简单的本地化Laravel | 70 | | 46 | [league/factory-muffin](https://github.com/thephpleague/factory-muffin) | 529911 | 441 | 这个包的目标是为了测试的目的能够快速创建对象。 | 71 | | 47 | [vinkla/hashids](https://github.com/vinkla/laravel-hashids) | 523384 | 907 | 拉拉维尔的哈希兹桥。 | 72 | | 48 | [orchestra/testbench](https://github.com/orchestral/testbench) | 518336 | 669 | 用于包开发的Laravel测试助手。 | 73 | | 49 | [baum/baum](https://github.com/etrepat/baum) | 510044 | 1682 | Baum是一个用于雄辩模型的嵌套模式的实现。 | 74 | | 50 | [laracasts/presenter](https://github.com/laracasts/Presenter) | 467441 | 610 | 主持人简单视图 | 75 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "godruoyi/laravel-popular-packages", 3 | "description": "The Best Image Ocr SDK For BAT.", 4 | "keywords": ["ocr", "image", "百度OCR", "腾讯OCR", "阿里云OCR"], 5 | "homepage": "http://github.com/godruoyi", 6 | "type": "project", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "godruoyi", 11 | "email": "godruoyi@gmail.com" 12 | } 13 | ], 14 | "require": { 15 | "guzzlehttp/guzzle": "^6.3", 16 | "symfony/filesystem": "^3.3" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "Godruoyi\\Packagist\\": "src/" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Packagist.php: -------------------------------------------------------------------------------- 1 | 'desc']; 25 | 26 | protected $defaultUrl = ''; 27 | 28 | protected $translator; 29 | 30 | /** 31 | * Register Client Instance 32 | * 33 | * @param string $applicationId 34 | * @param string $apiKey 35 | */ 36 | public function __construct($applicationId, $apiKey, $savePath = null, $requestUrl = '') 37 | { 38 | $this->applicationId = $applicationId; 39 | $this->apiKey = $apiKey; 40 | 41 | $this->defaultUrl = $requestUrl; 42 | $this->savePath = $savePath; 43 | } 44 | 45 | /** 46 | * Search top from Packagist 47 | * 48 | * @param string $keyword 49 | * @param int $perPage 50 | * 51 | * @return array 52 | */ 53 | public function search($keyword = 'laravel', $perPage = null) 54 | { 55 | $this->keyword = $keyword; 56 | $this->perPage = 0 | $perPage; 57 | 58 | $this->viaPackageFilter($keyword); 59 | 60 | $requestData = [ 61 | 'headers' => ['content-type' => 'application/json'], 62 | 'query' => $this->buildQueryString(), 63 | 'body' => $this->buildFormData(), 64 | 'verify'=> false 65 | ]; 66 | 67 | echo "Start search,the keyword: '{$keyword}', per-page: '{$perPage}'\r\n"; 68 | 69 | try { 70 | $result = $this->getHttpClient()->request('POST', $this->getRequestUrl(), $requestData); 71 | 72 | return $this->write($this->parseAndExceptPackages($result)); 73 | } catch (\GuzzleHttp\Exception\ClientException $e) { 74 | if ($e->hasResponse()) { 75 | $response = (string) $e->getResponse(); 76 | } else { 77 | $response = $e->getMessage(); 78 | } 79 | 80 | echo "Request failure,response: \r\n{$response}\r\n\r\n"; 81 | } 82 | } 83 | 84 | /** 85 | * Write Result to path 86 | * 87 | * @param array $result 88 | * 89 | * @return bool 90 | */ 91 | protected function write(array $results) 92 | { 93 | echo "Fetch done,start write...\r\n"; 94 | 95 | $fs = new Filesystem(); 96 | 97 | if (! empty($this->orderBy)) { 98 | $results = $this->sortBy($results, key($this->orderBy), current($this->orderBy)); 99 | } 100 | 101 | foreach ($results as $index => $result) { 102 | $name = $result['name']; 103 | $description = is_null($this->translator) ? $result['description'] : $this->translator->trans($result['description']); 104 | $repository = $result['repository']; 105 | $downloads = $result['downloads']; 106 | $favers = $result['favers']; 107 | $number = $index + 1; 108 | 109 | $str = "| {$number} | [{$name}]({$repository}) | {$downloads} | {$favers} | {$description} |\r\n"; 110 | 111 | $fs->appendToFile($this->getResultSavePath(), $str); 112 | } 113 | } 114 | 115 | /** 116 | * Parse Response To array 117 | * 118 | * @param GuzzleHttp\Psr7\Response $response 119 | * 120 | * @return array 121 | */ 122 | public function parseAndExceptPackages(\GuzzleHttp\Psr7\Response $response) 123 | { 124 | $body = (string) $response->getBody(); 125 | 126 | $result = json_decode($body, true); 127 | 128 | if (json_last_error() !== JSON_ERROR_NONE) { 129 | echo "Formatted json failed.\r\n"; 130 | exit; 131 | } 132 | 133 | $results = $result['results'][0]['hits'] ?? []; 134 | $data = []; 135 | 136 | foreach ($results as $package) { 137 | if ($this->shouleExceptPakage($package['name'])) { 138 | continue; 139 | } 140 | 141 | $data[] = [ 142 | 'description' => $package['description'], 143 | 'repository' => $package['repository'], 144 | 'downloads' => $package['meta']['downloads'], 145 | 'favers' => $package['meta']['favers'], 146 | 'name' => $package['name'] 147 | ]; 148 | } 149 | 150 | return $data; 151 | } 152 | 153 | /** 154 | * Except Package 155 | * 156 | * @param array $packages 157 | * 158 | * @return static 159 | */ 160 | public function except(array $packages = []) 161 | { 162 | $this->exceptPackage = array_merge($this->exceptPackage, $packages); 163 | 164 | return $this; 165 | } 166 | 167 | /** 168 | * Order BY 169 | * 170 | * @param string $key 171 | * @param string $order 172 | * 173 | * @return static 174 | */ 175 | public function orderBy($key, $order = 'desc') 176 | { 177 | $this->orderBy = [$key => $order]; 178 | 179 | return $this; 180 | } 181 | 182 | /** 183 | * sortBy 184 | * 185 | * @param array $results 186 | * @param string $name 187 | * @param string $order 188 | * 189 | * @return array 190 | */ 191 | protected function sortBy(array $results, $name, $order = 'desc') 192 | { 193 | usort($results, function ($package1, $package2) use ($order, $name) { 194 | if ($package1[$name] == $package2[$name]) { 195 | return 0; 196 | } 197 | 198 | if (strtolower($order) === 'desc') { 199 | return ($package1[$name] < $package2[$name]) ? 1 : -1; 200 | } 201 | 202 | return ($package1[$name] < $package2[$name]) ? -1 : 1; 203 | }); 204 | 205 | return $results; 206 | } 207 | 208 | /** 209 | * Laravel package filter 210 | * 211 | * @param string $keyword 212 | * 213 | * @return void 214 | */ 215 | protected function viaPackageFilter($keyword) 216 | { 217 | if (strtolower($keyword) == 'laravel') { 218 | $this->except($this->exceptDefaultLaravelPackage()); 219 | } 220 | } 221 | 222 | /** 223 | * Default laravel except package 224 | * 225 | * @return array 226 | */ 227 | public function exceptDefaultLaravelPackage(): array 228 | { 229 | return [ 230 | 'laravel/*' 231 | ]; 232 | } 233 | 234 | /** 235 | * Set result path 236 | * 237 | * @param string $path 238 | * 239 | * @return static 240 | */ 241 | public function setResultPath($path) 242 | { 243 | $this->savePath = $path; 244 | 245 | return $this; 246 | } 247 | 248 | /** 249 | * Shoule except 250 | * 251 | * @param string $name like godruoyi/ocr 252 | * 253 | * @return [bool 254 | */ 255 | public function shouleExceptPakage($name) 256 | { 257 | list($firstName, $secondName) = explode('/', $name); 258 | 259 | foreach ($this->exceptPackage as $ePackage) { 260 | list($eFirstName, $eSecondName) = explode('/', $ePackage); 261 | 262 | if (($ePackage == $name) || ($eSecondName == '*' && $eFirstName == $firstName)) { 263 | return true; 264 | } 265 | } 266 | 267 | return false; 268 | } 269 | 270 | /** 271 | * Build Request Body Form data 272 | * 273 | * @return string 274 | */ 275 | protected function buildFormData(): string 276 | { 277 | return sprintf( 278 | '{"requests":[{"indexName":"packagist","params":"hitsPerPage=%s&facetFilters=%s"}]}', 279 | ($this->perPage <= 0 ? 50 : $this->perPage), 280 | urlencode(json_encode([["tags:{$this->keyword}"]])) 281 | ); 282 | } 283 | 284 | /** 285 | * Build Request Query String 286 | * 287 | * @return array 288 | */ 289 | protected function buildQueryString(): array 290 | { 291 | return [ 292 | 'x-algolia-application-id' => $this->applicationId, 293 | 'x-algolia-api-key' => $this->apiKey, 294 | ]; 295 | } 296 | 297 | /** 298 | * Get Http Client Instance 299 | * 300 | * @return \GuzzleHttp\Client 301 | */ 302 | protected function getHttpClient() 303 | { 304 | return new Client(); 305 | } 306 | 307 | /** 308 | * Get Save Path 309 | * 310 | * @return string 311 | */ 312 | protected function getResultSavePath(): string 313 | { 314 | return $this->savePath ?: $this->getDefaultResultFilePath(); 315 | } 316 | 317 | /** 318 | * Get Request url 319 | * 320 | * @return string 321 | */ 322 | protected function getRequestUrl(): string 323 | { 324 | return empty($this->defaultUrl) ? 'http://m58222sh95-2.algolianet.com/1/indexes/*/queries' : $this->defaultUrl; 325 | } 326 | 327 | /** 328 | * Get Default Result file path 329 | * 330 | */ 331 | protected function getDefaultResultFilePath(): string 332 | { 333 | return __DIR__ . '/../result.md'; 334 | } 335 | 336 | /** 337 | * Set Translator 338 | * 339 | * @param string $appid 340 | * @param string $secret 341 | * 342 | * @return 343 | */ 344 | public function translate(string $appid, string $secret) 345 | { 346 | $this->translator = new Service\YoudaoTranslate($appid, $secret); 347 | 348 | return $this; 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /src/Service/BaiduTranslate.php: -------------------------------------------------------------------------------- 1 | appId = $appId; 27 | $this->secret = $secret; 28 | } 29 | 30 | public function trans(string $keyword, string $form = 'en', string $to = 'zh'): string 31 | { 32 | $this->keyword = $keyword; 33 | 34 | try { 35 | return $this->toString($this->getHttpClient()->get(self::API_HTTPS, $this->buildRequestParam($keyword, $form, $to))); 36 | } catch (Exception $e) { 37 | return $keyword; 38 | } 39 | } 40 | 41 | public function toString($response) 42 | { 43 | if ($response instanceof \GuzzleHttp\Psr7\Response) { 44 | $response = json_decode((string) $response->getBody(), true); 45 | 46 | if (json_last_error() === JSON_ERROR_NONE && ! empty($response['trans_result'][0]['dst'])) { 47 | return $response['trans_result'][0]['dst']; 48 | } 49 | } 50 | 51 | return $this->keyword; 52 | } 53 | 54 | /** 55 | * Get Http Client Instance 56 | * 57 | * @return \GuzzleHttp\Client 58 | */ 59 | protected function getHttpClient() 60 | { 61 | return new Client(); 62 | } 63 | 64 | public function buildRequestParam(string $keyword, string $form = 'en', string $to = 'zh') 65 | { 66 | return [ 67 | // 'headers' => ['content-type' => 'application/json'], 68 | 'query' => [ 69 | 'q' => $keyword = $this->toUTF8($keyword), 70 | 'from' => $form, 71 | 'to' => $to, 72 | 'appid' => 0 | $this->appId, 73 | 'salt' => 0 | $salt = mt_rand(10086, 99999), 74 | 'sign' => $this->sign($keyword, $salt) 75 | ], 76 | 'verify'=> false, 77 | ]; 78 | } 79 | 80 | public function toUTF8(string $word) 81 | { 82 | return mb_convert_encoding($word, 'UTF-8', 'auto'); 83 | } 84 | 85 | public function sign(string $keyword, string $salt): string 86 | { 87 | return md5(join('', [ 88 | 0 | $this->appId, 89 | $keyword, 90 | 0 | $salt, 91 | $this->secret, 92 | ])); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Service/YoudaoTranslate.php: -------------------------------------------------------------------------------- 1 | appId = $appId; 21 | $this->secret = $secret; 22 | } 23 | 24 | public function trans(string $keyword, string $form = 'EN', string $to = 'zh-CHS'): string 25 | { 26 | $keyword = trim($keyword); 27 | $this->keyword = $keyword; 28 | 29 | try { 30 | return $this->toString($this->getHttpClient()->get(self::API_HTTPS, $this->buildRequestParam($keyword, $form, $to))); 31 | } catch (Exception $e) { 32 | var_dump($e->getMessage()); 33 | return $keyword; 34 | } 35 | } 36 | 37 | public function toString($response) 38 | { 39 | if ($response instanceof \GuzzleHttp\Psr7\Response) { 40 | $response = json_decode((string) $response->getBody(), true); 41 | 42 | if (json_last_error() === JSON_ERROR_NONE && ! empty($response['translation'][0])) { 43 | return $response['translation'][0]; 44 | } 45 | } 46 | 47 | return $this->keyword; 48 | } 49 | 50 | /** 51 | * Get Http Client Instance 52 | * 53 | * @return \GuzzleHttp\Client 54 | */ 55 | protected function getHttpClient() 56 | { 57 | return new Client(); 58 | } 59 | 60 | public function buildRequestParam(string $keyword, string $form = 'en', string $to = 'zh') 61 | { 62 | return [ 63 | // 'headers' => ['content-type' => 'application/json'], 64 | 'query' => [ 65 | 'q' => $keyword = $this->toUTF8($keyword), 66 | 'from' => $form, 67 | 'to' => $to, 68 | 'appKey' => $this->appId, 69 | 'salt' => $salt = mt_rand(10086, 99999), 70 | 'sign' => $this->sign($keyword, $salt) 71 | ], 72 | 'verify'=> false, 73 | ]; 74 | } 75 | 76 | public function toUTF8(string $word) 77 | { 78 | return mb_convert_encoding($word, 'UTF-8', 'auto'); 79 | } 80 | 81 | public function sign(string $keyword, string $salt): string 82 | { 83 | return md5(join('', [ 84 | $this->appId, 85 | $keyword, 86 | $salt, 87 | $this->secret, 88 | ])); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /test.php: -------------------------------------------------------------------------------- 1 | except(['composer/installers', 'illuminate/*']) 11 | ->orderBy('downloads', 'desc') 12 | ->translate('28b56d1aa3fab6bd', 'wJWR0fZp3nfAeL7UMpTPpvecgGsdLYmz') 13 | ->setResultPath(__DIR__ . '/test.md') 14 | ->search('laravel', 120); 15 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/godruoyi/laravel-package-top/36f8deeda1f59b84bce62da28b0a0f3e55868b7b/tests/.gitkeep --------------------------------------------------------------------------------