Silex和Github在每种语言和地区的受欢迎用户

The Github API V3 is a very powerful set of API endpoints that you can use to retrieve useful information about your repositories, activities, and events. Not only that, it allows you to access public information on others. The fact that it has libraries in many languages and platforms is also a big plus; it allows you to get down to writing code very fast.

Github API V3是一组非常强大的API端点,可用于检索有关您的存储库,活动和事件的有用信息。 不仅如此,它还允许您访问其他人的公共信息。 它具有多种语言和平台的库 ,这也是一大优势。 它使您可以很快地编写代码。

The data you can get through the GitHub API V3 is mostly what you can see on the GitHub web interface, except you can use the data in your application to come to interesting conclusions. That is what we are going to do in this article.

通过GitHub API V3可以获得的数据大部分是在GitHub Web界面上看到的,除了可以在应用程序中使用这些数据得出有趣的结论。 这就是我们在本文中要做的。

Younes Rafie has written an article titled How to Use Github’s API with PHP, in which he introduces a lot of what we are talking about here, although in a different fashion. If you haven’t read that article, though, do not fear! We have you covered.

尤尼斯·拉菲(Younes Rafie )写了一篇名为“ 如何在PHP中使用Github的API ”的文章,尽管其中以不同的方式介绍了他在本文中谈论的内容。 但是,如果您尚未阅读该文章,请不要害怕! 我们有你覆盖。

Github logo

这个概念 (The Concept)

As Brandon Savage notes in his article, The definitive guide to contributing to open source:

正如布兰登·萨维奇(Brandon Savage)在其文章《对开源做出贡献的权威指南》中所指出的:

There are millions of PHP developers, but only a (large) handful of contributors, authors and maintainers of open source software. Packagist reports a little under 50,000 packages in the PHP ecosystem. This is a huge number of open source packages, but is a small number compared to the PHP developers in the world.

有数百万PHP开发人员,但是只有少数(大量)开源软件的贡献者,作者和维护者。 Packagist报告说,PHP生态系统中的软件包不足50,000个。 这是大量的开源软件包,但是与世界上PHP开发人员相比,数量很少。

Now, what if there was a web service in which we could specify a location and a language (e.g. PHP) and get a sorted list of contributors to open-source? It would certainly make Brandon very happy.

现在,如果有一个Web服务可以在其中指定位置和语言(例如PHP)并获得开放源代码的排序列表,该怎么办? 这肯定会让布兰登非常高兴。

In our web service, we will have one endpoint (i.e. action, URL) that shows the most popular ten creators. The most popular creators are the people in a location who have the largest number of stargazers. For this, we will retrieve each person’s repositories and add up the number of times each one has been starred.

在我们的Web服务中,我们将有一个端点(即动作,URL)来显示最受欢迎的十个creators 。 最受欢迎的creators是该地区的观星人数最多的人。 为此,我们将检索每个人的存储库并加总每个人加注星标的次数。

The GitHub Awards project does something similar, although in a much more complicated manner. It uses tools such as the GitHub Archive, which are outside of the scope of this article. Younes Rafie covered that approach somewhat, too, in this post. However, what we’ll do here is simply sort users by their number of followers, since that is a good indication of popularity as well. To view the full source code of this app, check out its Github repo.

GitHub Awards项目的功能类似,但方式更为复杂。 它使用了诸如GitHub Archive之类的工具,这些工具不在本文讨论范围之内。 尤尼斯·拉菲(Younes Rafie)在这篇文章中也对此方法做了一些介绍。 但是,我们在这里要做的只是按照关注者的数量对用户进行排序,因为这也很好地表明了受欢迎程度。 要查看此应用程序的完整源代码,请查看其Github repo

整装待发 (Gearing Up)

设置开发机器 (Setting Up the Development Machine)

The easiest way to get started is to use either Laravel Homestead, or our very own Homestead Improved. Regardless of which one you use, if you open your homestead.yaml configuration file, you will see the default configuration, which is to have a site called homestead.app which loads your php files from ~/Code.

最简单的入门方法是使用Laravel Homestead或我们自己的Homestead Improvementd 。 无论使用哪种格式,如果打开homestead.yaml配置文件,都会看到默认配置,即拥有一个名为homestead.app的站点,该站点从~/Code加载php文件。

sites:
    - map: homestead.app
      to: /home/vagrant/Code/Laravel/public

获取Silex并设置Homestead.yaml (Getting Silex and Setting Up Homestead.yaml)

Being a micro-framework, Silex doesn’t have many rules or conventions. However, it helps to read this article to absorb some basics. If you don’t feel like switching between articles, we’ll link to relevant sections of the Silex documentation throughout this tutorial.

作为一个微框架,Silex没有太多规则或约定。 但是,阅读本文有助于吸收一些基础知识。 如果您不想在文章之间切换,我们将在整个教程中链接到Silex文档的相关部分。

As you might know, Silex puts its index.php file in the web directory as per Symfony conventions. So, your webroot will actually be ~/Code/silex/web, rather than ~/Code/Laravel/public. Let’s go into the sites section of homestead.yaml and fix that:

如您所知,Silex根据Symfony约定将其index.php文件放入web目录。 因此,您的webroot实际上是~/Code/silex/web ,而不是~/Code/Laravel/public 。 让我们进入homestead.yamlsites部分并修复该问题:

sites:
    - map: homestead.app
      to: /home/vagrant/Code/silex/web

Then, punch in vagrant up to boot up the VM and once it’s done, SSH into the VM with vagrant ssh. Inside, we do the following to initiate a new working Silex instance:

然后,输入vagrant up以启动虚拟机,完成后,使用vagrant ssh SSH进入虚拟机。 在内部,我们执行以下操作以启动新的工作Silex实例:

cd Code
composer create-project silex/silex

Once this procedure is complete (might take a while) create a subfolder in the silex folder called web and inside it a file index.php with the contents:

一旦完成此过程(可能需要一点时间),即可在silex文件夹中创建一个名为web的子文件夹,并在其中包含内容的index.php文件:

<?php

require_once __DIR__.'/../vendor/autoload.php';

$app = new Silex\Application();

$app->get('/', function(){
    return "Hello world";
});

$app->run();

If you open up homestead.app:8000 in your browser now, you should see “Hello World” (provided homestead.app is in your hosts file, as per instructions).

如果现在在浏览器中打开homestead.app:8000 ,您应该会看到“ Hello World”( 按照说明 ,在hosts文件中提供了homestead.app )。

Congratulations! You are now ready to roll!

恭喜你! 您现在可以开始滚动了!

GitHub API V3入门 (Getting Started With GitHub API V3)

We’re going to use KNPLabs’ PHP GitHub API library to retrieve data from GitHub through its GitHub API V3. Let’s add it to our composer.json file by executing the command: composer require knplabs/github-api ~1.4.

我们将使用KNPLabs的PHP GitHub API库通过GitHub API V3从GitHub检索数据。 让我们通过执行以下命令将其添加到composer.json文件中: composer require knplabs/github-api ~1.4

Let’s turn on the debug mode by setting $app['debug'] to true, and make a request to the GitHub API V3 to give us the details of a user named parhamdoustdar. Update index.php.

让我们通过将$app['debug']true来打开调试模式,并向GitHub API V3发出请求,以向我们提供名为parhamdoustdar的用户的详细信息。 更新index.php

<?php
require_once __DIR__.'/../vendor/autoload.php';

use Github\Client;
use Silex\Application;

$app = new Application();
$app['debug'] = true;

$app->get('/', function (Application $app) {
    $client = new Client();
    $parham = $client->user()->show('parhamdoustdar');
    
    return $app->json($parham);
});

$app->run();

If you go to http://homestead.app:8000, you should see parhamdoustdar’s details in json:

如果您访问http://homestead.app:8000 ,则应该在json中看到parhamdoustdar的详细信息:

{
    "login":"parhamdoustdar",
    "id":352539,
    "avatar_url":"https:\/\/avatars.githubusercontent.com\/u\/352539?v=3",
    "gravatar_id":"","url":"https:\/\/api.github.com\/users\/parhamdoustdar",
    "html_url":"https:\/\/github.com\/parhamdoustdar",
    "followers_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/followers",
    "following_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/following{\/other_user}",
    "gists_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/gists{\/gist_id}",
    "starred_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/starred{\/owner}{\/repo}",
    "subscriptions_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/subscriptions",
    "organizations_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/orgs",
    "repos_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/repos",
    "events_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/events{\/privacy}",
    "received_events_url":"https:\/\/api.github.com\/users\/parhamdoustdar\/received_events",
    "type":"User",
    "site_admin":false,
    "name":"Parham Doustdar",
    "company":"TENA",
    "blog":"http:\/\/www.parhamdoustdar.com",
    "location":"Tehran",
    "email":"parham90@gmail.com",
    "hireable":true,
    "bio":null,
    "public_repos":9,
    "public_gists":2,
    "followers":3,
    "following":0,
    "created_at":"2010-08-03T07:56:17Z",
    "updated_at":"2015-03-01T20:01:26Z"}

If you didn’t understand what exactly our controller is doing, don’t fret! We’ll go through it together.

如果您不了解我们的控制器究竟在做什么,请不要担心! 我们将一起经历它。

On line 8, we’re turning on the debug mode as previously mentioned.

在第8行,我们打开了前面提到的调试模式。

Inside the anonymous function that will be called whenever the root route (/) is accessed, we create an instance of Github\Client. Note that we’ve added an argument which is of type Silex\Application. As noted in the usage section of the Silex manual:

在访问根路由( / )时将调用的匿名函数内部,我们创建了Github\Client的实例。 请注意,我们添加了一个Silex\Application类型的参数。 如Silex手册的用法部分所述:

The current Application is automatically injected by Silex to the Closure thanks to the type hinting.

由于类型提示,Silex将当前应用程序自动注入到Closure中。

In the next line, we’re calling the user() method on the client object to get an object of type Github\Api\User, which is used to get information on users. We then simply call show() on this object, passing in the username we want to get information on.

在下一行中,我们在client对象上调用user()方法以获取Github\Api\User类型的对象,该对象用于获取有关用户的信息。 然后,我们只需在此对象上调用show() ,传入我们想要获取其信息的用户名。

The last line uses the json() helper method on the Silex\Application object to render our example json response.

最后一行在Silex\Application对象上使用json()帮助程序方法来呈现示例json响应。

应用目录 (The App Directory)

You might have noticed that our project doesn’t have a location to put our source code in. Having one index.php file is fine when you are writing a small piece of code to check that everything is working smoothly, but it’s now time for us to create a folder to house our app’s source code.

您可能已经注意到,我们的项目没有放置源代码的位置。编写一小段代码以检查一切是否正常时,拥有一个index.php文件就可以了,但是现在该我们创建一个文件夹来存放我们应用程序的源代码。

To do this, create a folder in your silex directory, next to your web folder, and call it App. With that out of the way, let’s edit composer.json and add the autoload information:

为此,请在您的silex目录中的web文件夹旁边创建一个文件夹,并将其命名为App 。 这样,让我们​​编辑composer.json并添加自动加载信息:

{
    ...
    "autoload": {
        "psr-0": { "Silex": "src/" },
        "psr-4": {
            "App\\": "App/"
        }
    },

}

Next, run composer dump-autoload to regenerate your autoload files. We are now ready to get to the real thing!

接下来,运行composer dump-autoload重新生成自动加载文件。 现在,我们准备好去了解真实的事物!

某个位置的GitHub用户 (GitHub Users in a Location)

The first thing we need for our toplist is to get a list of usernames in a particular location that have repositories in the specified language. We can use the Search Users API for this.

我们所需的第一件事是获取特定位置的用户名列表,该用户名具有使用指定语言的存储库。 我们可以为此使用Search Users API

If you look at that page, you will see that we can specify multiple parameters when searching for users. However, what we’re interested in is location and language, which can be specified in the q parameter. If you have used the GitHub search box before, you will notice that the q parameter is what you’d type into that text field.

如果查看该页面,将会看到我们在搜索用户时可以指定多个参数。 但是,我们感兴趣的是locationlanguage ,它们可以在q参数中指定。 如果您以前使用过GitHub搜索框,则会注意到q参数是您要在该文本字段中键入的内容。

Let’s go ahead and create a service that searches for users who live in the location we want, and have repositories in the programming language we need. We’ll call it UserSearcher and put it into App/Services.

让我们继续创建一个服务,该服务搜索居住在我们想要的位置并拥有我们所需编程语言存储库的用户。 我们将其称为UserSearcher并将其放入App/Services

<?php
namespace App\Services;

use Github\Client;
class UserSearcher
{
    
    /**
     * @var Client
     */
    protected $client;
    
    public function __construct(Client $client)
    {
        $this->client = $client;
    }
    
    public function retrieveByLocationAndLanguage($location, $language)
    {
        $searchString = "location:${location} language:${language}";
        $results = $this->fetchSearchResults($searchString, 10);
        
        return $this->extractUsernames($results);
    }
    
    protected function fetchSearchResults($searchString, $count)
    {
        $results = $this->client
            ->search()
            ->setPerPage($count)
            ->users($searchString, 'followers')
        ;
        
        return $results['items'];
    }
    
    protected function extractUsernames(array $results)
    {
        $usernames = [];
        
        foreach ($results as $result) {
            $usernames[] = $result['login'];
        }
        
        return $usernames;
    }
    
}

As you can see, the UserSearcher::retrieveByLocationAndLanguage() method first constructs a search string. If you send Tehran and PHP as the first and second arguments to this function respectively, the string will be location:Tehran language:PHP.

如您所见, UserSearcher::retrieveByLocationAndLanguage()方法首先构造一个搜索字符串。 如果将TehranPHP作为该函数的第一个和第二个参数发送,则字符串将为location:Tehran language:PHP

It then retrieves the list of top ten search results using Github\Client. As you have probably guessed, it first gets the search API object (Github\Api\Search) from the client, then sets perPage to 10, meaning that it will only request ten search results. Afterwards, it sends the search string to GitHub and returns the results. Note that the results of the search are sorted by the number of followers and in the items index of the returned array.

然后,它使用Github\Client检索前十个搜索结果的列表。 您可能已经猜到了,它首先从客户端获取搜索API对象( Github\Api\Search ),然后将perPage设置为10,这意味着它将仅请求十个搜索结果。 然后,它将搜索字符串发送到GitHub并返回结果。 请注意,搜索结果按关注者数量和返回数组的items索引排序。

The method extractUserNames() simply does what you’d expect: it loops through the results and adds each user’s login to an array, then returns it.

方法extractUserNames()只是完成您期望的事情:它遍历结果并将每个用户的login添加到数组中,然后返回它。

What do we have at this point? Ten usernames. Ten usernames that we can query for their repositories, and then add up the number of stargazers for all the repositories under that user’s name.

我们现在有什么? 十个用户名。 我们可以查询十个用户名,以查询其存储库,然后以该用户名为所有存储库加注星标的数量。

Ready?

准备?

仓库观星者 (Stargazers of Repositories)

Below is the code for our class, App\Services\StarGazerCalculator:

以下是我们的类App\Services\StarGazerCalculator

<?php
namespace App\Services;

use Github\Client;
class StarGazerCalculator
{
    
    /**
     * @var Client
     */
    protected $client;
    
    public function __construct(Client $client)
    {
        $this->client = $client;
    }
    
    public function calculateStarGazersByUsername($username)
    {
        $repositories = $this->client->user()->repositories($username);
        $repositories = $this->filterForkedRepositories($repositories);
        
        return $this->addStarGazersFromRepositories($repositories);
    }
    
    protected function filterForkedRepositories(array $repositories)
    {
        return array_filter($repositories, function($repository) {
            return $repository['fork'] === false;
        });
    }
    
    protected function addStarGazersFromRepositories(array $repositories)
    {
        return array_reduce($repositories, function($starGazersSoFar, $repository) {
            return $starGazersSoFar + $repository['stargazers_count'];
        });
    }
    
}

检索顶级创作者 (Retrieving Top Creators)

Now it’s time to start writing our final class, TopCreatorsRetriever. This class wraps up the functionality we want – it gets the most popular ten usernames using the UserSearcher class, and then loops through those users, using the StarGazerCalculator to get the number of stargazers for each user.

现在是时候开始编写我们的最终课程TopCreatorsRetriever 。 此类包装了我们想要的功能–它使用UserSearcher类获取最受欢迎的十个用户名,然后使用StarGazerCalculator遍历这些用户,以获取每个用户的观星人数。

<?php
namespace App\Services;

class TopCreatorsRetriever
{
    
    /**
     * @var UserSearcher
     */
    protected $searcher;
    
    /**
     * @var StarGazerCalculator
     */
    protected $calculator;
    
    public function __construct(UserSearcher $searcher, StarGazerCalculator $calculator)
    {
        $this->searcher = $searcher;
        $this->calculator = $calculator;
    }
    
    public function retrieve($location, $language)
    {
        $usernames = $this->searcher->retrieveByLocationAndLanguage($location, $language);
        $map = $this->createUserStarGazerMap($usernames);
        
        return $this->sortMapByStarGazers($map);
    }
    
    protected function createuserStarGazerMap(array $usernames)
    {
        $results = [];
        
        foreach ($usernames as $username) {
            $results[$username] = $this->calculator->calculateStarGazersByUsername($username);
        }
        
        return $results;
    }
    
    protected function sortMapByStarGazers(array $map)
    {
        arsort($map, SORT_NUMERIC);
        
        return $map;
    }
    
}

服务提供者 (The Service Provider)

As you may know, in order to add our classes to the dependency injection container provided with Silex, we need to create a service provider and then register it on the application. That means we need to create a service provider in order to use our newly written class TopCreatorsRetriever. We don’t need to register the other two classes though, because those two classes are there for internal use by our high-level class, TopCreatorsRetriever.

如您所知,为了将我们的类添加到Silex随附的依赖项注入容器中,我们需要创建一个服务提供程序 ,然后在应用程序上注册它 。 这意味着我们需要创建一个服务提供者,以使用我们新编写的类TopCreatorsRetriever 。 不过,我们不需要注册其他两个类,因为这两个类可供我们的高级类TopCreatorsRetriever内部使用。

Create a new folder under App/ and call it Providers. Then, create a file named TopCreatorsRetrieverServiceProvider.php which will house the code for our class.

App/下创建一个新文件夹,并将其命名为Providers 。 然后,创建一个名为TopCreatorsRetrieverServiceProvider.php的文件,该文件将TopCreatorsRetrieverServiceProvider.php我们类的代码。

<?php
namespace App\Providers;

use Silex\ServiceProviderInterface;
use Silex\Application;
use Github\Client;
use App\Services\UserSearcher;
use App\Services\StarGazerCalculator;
use App\Services\TopCreatorsRetriever;
class TopCreatorsRetrieverServiceProvider implements ServiceProviderInterface
{

    public function register(Application $app)
    {
        $app['topCreatorsRetriever'] = $app->share(function() {
            $client = new Client();
            $searcher = new UserSearcher($client);
            $calculator = new StarGazerCalculator($client);
            
            return new TopCreatorsRetriever($searcher, $calculator);
        });
    }

    public function boot(Application $app)
    {
        
    }
}

Note: Do not remove the empty boot() function. It is required to exist, even if it’s empty, so that our class would conform to the ServiceProviderInterface interface.

注意 :请勿删除空的boot()函数。 即使它为空,它也必须存在,以便我们的类符合ServiceProviderInterface接口。

在我们的控制器中使用TopCreatorsRetriever (Using TopCreatorsRetriever In Our Controller)

It’s finally time to see all our work in action. We will define a route in index.php called creators, that gets the location and language as arguments, and then returns a JSON array, with usernames as keys and the number of stargazers as values. Don’t forget that as noted before, we also need to register the service provider we created earlier.

现在终于该看到我们所有的工作了。 我们将在index.php定义一个名为creators的路由,该路由将locationlanguage作为参数,然后返回一个JSON数组,其中用户名为键,观星者的数量为值。 不要忘记,如前所述,我们还需要注册我们之前创建的服务提供商。

<?php
require_once __DIR__.'/../vendor/autoload.php';

use Silex\Application;
use App\Providers\TopCreatorsRetrieverServiceProvider;

$app = new Application();
$app['debug'] = true;
$app->register(new TopCreatorsRetrieverServiceProvider());

$app->get('/creators/{location}/{language}', function (Application $app, $location, $language) {
    $data = $app['topCreatorsRetriever']->retrieve($location, $language);
    return $app->json($data);
});

$app->run();

Very simple. The only things that have changed are the registration of our service provider, and our route, which contains two lines only:

很简单。 唯一发生变化的是我们的服务提供商的注册以及我们的路线,其中仅包含两行:

  1. The first line gets the data from the TopCreatorsRetriever class, and

    第一行从TopCreatorsRetriever类获取数据,然后

  2. The second line turns that data into json.

    第二行将数据转换为json。

Now, if you send a request to http://homestead.app:8000/creators/Tehran/PHP, you will see all the package creators with the highest number of stargazers who live in Tehran:

现在,如果您向http://homestead.app:8000/creators/Tehran/PHP发送请求,您将看到居住在德黑兰的观星人数最多的所有软件包创建者:

{
    "sallar":198,
    "sepehr":86,
    "reshadman":49,
    "moein7tl":49,
    "alijmlzd":13,
    "atkrad":4,
    "AmirHossein":3,
    "Yousha":0,
    "voltan":0,
    "zoli":0
}

Congratulations! You now know who the most popular package creators are in any area!

恭喜你! 您现在知道在任何地区最受欢迎的包装创作者!

结论 (Conclusion)

We now have an application which gathers meaningful data from GitHub through a very basic mechanism: we retrieve the top users in an area who have a repository in the language we want, and add up the stargazers for all of their repositories.

现在,我们有了一个应用程序,该应用程序通过一种非常基本的机制从GitHub收集有意义的数据:我们检索某个区域中拥有所需语言存储库的顶级用户,并为所有存储库加注星标。

Hopefully, this tutorial has taught you something new and useful. Please leave your feedback in the comments below and don’t forget you can check out the full source code here!

希望本教程教给您一些新的有用的知识。 请在下面的评论中留下您的反馈,不要忘记您可以在此处查看完整的源代码!

翻译自: https://www.sitepoint.com/popular-users-per-language-region-silex-github/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值