ashallendesign/favicon-fetcher

用于获取网站favicon的Laravel包。

v3.6.0 2024-07-08 08:38 UTC

README

Favicon Fetcher

Latest Version on Packagist Total Downloads PHP from Packagist GitHub license

目录

概述

一个用于从网站获取favicon的Laravel包。

安装

要求

该包已开发和测试,以确保与以下最低要求兼容

  • PHP 8.0
  • Laravel 8.0

安装包

您可以通过Composer安装该包

composer require ashallendesign/favicon-fetcher

发布配置

然后,您可以使用以下命令发布包的配置文件

php artisan vendor:publish --provider="AshAllenDesign\FaviconFetcher\FaviconFetcherProvider"

使用方法

获取favicon

现在您已经安装了包,您可以从不同的网站开始获取favicon。

使用fetch方法

要从网站获取favicon,您可以使用fetch方法,它将返回一个AshAllenDesign\FaviconFetcher\Favicon实例。

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetch('https://ashallendesign.co.uk');

使用fetchOr方法

如果您希望提供一个默认值以备找不到favicon时使用,您可以使用fetchOr方法。

例如,如果您想在找不到favicon时使用默认图标(https://example.com/favicon.ico),则您的代码可能如下所示

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetchOr('https://ashallendesign.co.uk', 'https://example.com/favicon.ico');

此方法还接受一个Closure作为第二个参数,如果您希望运行一些自定义逻辑。通过fetchOr方法传递的第一个参数的url字段可在闭包中使用。例如,要使用闭包,则您的代码可能如下所示

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetchOr('https://ashallendesign.co.uk', function ($url) {
    // Run extra logic here...

    return 'https://example.com/favicon.ico';
});

使用fetchAll方法

有时您可能想要获取给定网站的不同大小的favicon。要获取不同大小的favicon,您可以使用fetchAll方法,它将返回一个AshAllenDesign\FaviconFetcher\Collections\FaviconCollection实例。此集合包含AshAllenDesign\FaviconFetcher\Favicon的实例。例如,要获取网站的全部favicon,您可以使用如下所示的fetchAll方法

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicons = Favicon::fetchAll('https://ashallendesign.co.uk');

FaviconCollection类扩展了Illuminate\Support\Collection类,因此您可以使用Collection类上所有可用的方法。

它还包括一个largest方法,您可以使用它来获取尺寸最大的favicon。值得注意的是,如果favicon的大小未知,则在确定哪个是最大的时,它将被视为具有0x0px的大小。例如,您可以使用如下所示的largest方法

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$largestFavicon = Favicon::fetchAll('https://ashallendesign.co.uk')->largest();

FaviconCollection还提供了一个largestByFileSize方法,您可以使用它来获取文件大小最大的favicon。如果您发现该包无法检测给定网站图标的尺寸,并且因此无法检测到最大的图标,则可能需要进行此操作。此方法基于假设文件大小越大,图像尺寸越大。例如,您可以使用如下所示的largestByFileSize方法

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$largestFavicon = Favicon::fetchAll('https://ashallendesign.co.uk')->largestByFileSize();

注意:只有 http 驱动支持检索给定网站的所有 favicons。因此,fetchAll 方法不支持回退。将来可能会为其他驱动程序和回退添加支持。

使用fetchAllOr方法

如果您想提供一个默认值,在无法找到网站的所有 favicons 时使用,可以使用 fetchAllOr 方法。

例如,如果您想使用默认图标(https://example.com/favicon.ico),如果无法找到 favicons,则您的代码可能如下所示

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetchAllOr('https://ashallendesign.co.uk', 'https://example.com/favicon.ico');

此方法还接受一个作为第二个参数的 Closure,如果您想运行一些自定义逻辑。在 fetchAllOr 方法中作为第一个参数传递的 url 字段可用于闭包中。例如,要使用闭包,则您的代码可能如下所示

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetchAllOr('https://ashallendesign.co.uk', function ($url) {
    // Run extra logic here...

    return 'https://example.com/favicon.ico';
});

异常

默认情况下,如果无法找到 URL 的 favicons,则 fetch 方法将返回 null。但是,如果您希望抛出异常,可以使用 Favicon 面具上可用的 throw 方法。这意味着如果无法找到 favicons,将抛出 AshAllenDesign\FaviconFetcher\Exceptions\FaviconNotFoundException

要启用抛出异常,则您的代码可能如下所示

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::throw()->fetch('https://ashallendesign.co.uk');

如果您尝试检索 favicons,并且请求超时或未在 URL 中找到网站,将抛出 AshAllenDesign\FaviconFetcher\Exceptions\ConnectionException。即使未使用 throw 方法,也会抛出。

驱动程序

Favicon Fetcher 提供了使用不同驱动程序从网站检索 favicons 的功能。

可用的驱动程序

默认情况下,Favicon Fetcher 随附 5 个驱动程序:httpgoogle-shared-stufffavicon-kitunavatarfavicon-grabber

http 驱动程序通过尝试解析网页返回的 HTML 中的 "icon" 和 "shortcut icon" 链接元素来检索 favicons。如果找不到,它将尝试根据常用默认值猜测 favicons 的 URL。

google-shared-stuff 驱动程序使用 Google Shared Stuff API 检索 favicons。

favicon-kit 驱动程序使用 Favicon Kit API 检索 favicons。

unavatar 驱动程序使用 Unavatar API 检索 favicons。

favicon-grabber 驱动程序使用 Favicon Grabber API 检索 favicons。

如何选择驱动程序

重要的是要记住,google-shared-stufffavicon-kitunavatar 驱动程序与第三方 API 交互以检索 favicons。因此,这意味着某些数据将共享到外部服务。

但是,http 驱动程序不使用任何外部服务,并且直接查询您尝试从中检索 favicons 的网站。由于此包是新的,http 驱动程序在尝试从网站检索 favicons 时可能不是 100% 准确。因此,理论上,http 驱动程序应提供更好的隐私,但可能不如其他驱动程序准确。

选择驱动程序

您可以在发布后更改 favicon-fetcher 配置文件中的 default 字段来选择默认使用的驱动程序。该软件包最初启用 http 驱动程序作为默认驱动程序。

例如,如果您想将默认驱动程序更改为 favicon-kit,则可以按如下方式更新您的 favicon-fetcher 配置

return [

    // ...
        
    'default' => 'favicon-kit',
            
    // ...

]

如果您想动态设置驱动程序,可以通过在 Favicon 接口中使用 driver 方法来实现。例如,如果您想使用 google-shared-stuff 驱动程序,可以像这样操作:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::driver('google-shared-stuff')->fetch('https://ashallendesign.co.uk');

回退驱动程序

有时,特定的驱动程序可能无法为网站找到favicon。如果发生这种情况,您可以回退并尝试使用不同的驱动程序再次查找。

例如,如果我们想尝试使用 http 驱动程序来获取favicon,如果找不到则回退到 google-shared-stuff 驱动程序,代码可能如下所示:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::withFallback('google-shared-stuff')->fetch('https://ashallendesign.co.uk');

添加您自己的驱动程序

有时,您可能想要为获取favicon提供自己的自定义逻辑。为此,您可以构建自己的驱动程序并将其注册到包中以供使用。

首先,您需要创建自己的类并确保它实现了 AshAllenDesign\FaviconFetcher\Contracts\Fetcher 接口。例如,您的类可能如下所示:

use AshAllenDesign\FaviconFetcher\Contracts\Fetcher;
use AshAllenDesign\FaviconFetcher\Favicon;

class MyCustomDriver implements Fetcher
{
    public function fetch(string $url): ?Favicon
    {
        // Add logic here that attempts to fetch a favicon...
    }

    public function fetchOr(string $url, mixed $default): mixed
    {
        // Add logic here that attempts to fetch a favicon or return a default...
    }
}

创建新驱动程序后,您可以使用 Favicon 接口提供的 extend 方法将其注册到包中。您可能希望在一个服务提供者中这样做,以便在整个应用程序中设置和可用。

您可以这样注册自定义驱动程序:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

Favicon::extend('my-custom-driver', new MyCustomDriver());

现在,您已经注册了自定义驱动程序,您可以使用它来获取favicon,如下所示:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::driver('my-custom-driver')->fetch('https://ashallendesign.co.uk');

HTTP超时

Favicon Fetcher 提供了您设置所有驱动程序的连接超时和请求超时的能力。

连接超时是包将等待建立到网站连接的时间。请求超时是包将等待网站对请求做出响应的时间。

要实现这一点,您可以在发布配置文件后更新 favicon-fetcher.php 配置文件中的 connect_timeouttimeout 字段。例如,要将连接超时设置为5秒,将请求超时设置为10秒,可以像这样更新您的配置文件:

return [

    // ...
        
    'connect_timeout' => 5,

    'timeout' => 10,
            
    // ...

]

如果您不想设置超时,可以将值设置为 0

请注意,这些超时适用于 Favicon Fetcher 所做的所有 HTTP 请求,而不管使用的驱动程序是什么。

TLS验证

Favicon Fetcher 默认使用 TLS 验证,但这可以禁用。这在开发环境或您可能在与自签名证书或不受信任的证书颁发机构工作的环境中工作时可能很有用。

您可以在发布配置文件后更新 favicon-fetcher.php 配置文件中的 verify_tls 字段来禁用验证。

return [

    // ...
        
    'verify_tls' => false,
            
    // ...

]

或更新您的 .env 文件

FAVICON_FETCHER_VERIFY_TLS=false

HTTP用户代理

您可能会发现,在尝试检索favicon时,请求有时会被网站阻止。这可能是因为默认的 Guzzle User-Agent 标头被传递到请求中。

Favicon Fetcher 允许您设置包请求中使用的 User-Agent 标头。为此,您可以在发布配置文件后更新 favicon-fetcher.php 配置文件中的 user_agent 字段。例如,要将 User-Agent 标头设置为 My Custom User Agent,可以像这样更新您的配置文件:

return [

    // ...
        
    'user_agent' => 'My Custom User Agent',
            
    // ...

]

User-Agent 标头将设置在 Favicon Fetcher 所做的所有 HTTP 请求上,而不管使用的驱动程序是什么。

user_agent 配置字段已经在配置文件中配置为直接从 .env 文件中的 FAVICON_FETCHER_USER_AGENT 字段读取。因此,如果您想在 .env 文件中设置 User-Agent 标头,可以像这样操作:

FAVICON_FETCHER_USER_AGENT="My Custom User Agent"

存储favicon

在获取favicon后,您可能希望将它们存储在文件系统中,以便将来不需要再次获取。Favicon Fetcher 提供了两种您可以使用的方法来存储favicon:storestoreAs

使用store

如果您使用store方法,在存储之前将自动生成favicon的文件名。该方法的第一参数接受一个字符串,是favicon将存储的目录。您可以使用默认文件系统磁盘以以下方式存储favicon:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconPath = Favicon::fetch('https://ashallendesign.co.uk')->store('favicons');

// $faviconPath is now equal to: "/favicons/abc-123.ico"

如果您想使用不同的存储磁盘,可以将它作为store方法的可选第二个参数传递。例如,要将favicon存储在S3上,您的代码可以使用以下内容:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconPath = Favicon::fetch('https://ashallendesign.co.uk')->store('favicons', 's3');

// $faviconPath is now equal to: "/favicons/abc-123.ico"

使用storeAs

如果您使用storeAs方法,您将能够定义文件将被存储为的文件名。该方法的第一参数接受一个字符串,是favicon将被存储的目录。第二个参数指定favicon的文件名(不包括文件扩展名)。您可以使用默认文件系统磁盘以以下方式存储favicon:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconPath = Favicon::fetch('https://ashallendesign.co.uk')->storeAs('favicons', 'ashallendesign');

// $faviconPath is now equal to: "/favicons/ashallendesign.ico"

如果您想使用不同的存储磁盘,可以将它作为storeAs方法的可选第三个参数传递。例如,要将favicon存储在S3上,您的代码可以使用以下内容:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconPath = Favicon::fetch('https://ashallendesign.co.uk')->storeAs('favicons', 'ashallendesign', 's3');

// $faviconPath is now equal to: "/favicons/ashallendesign.ico"

缓存favicon

除了存储favicon之外,该包还允许您缓存favicon的URL。如果您不想存储本地文件副本并想使用网站使用的favicon的外部版本,这可以非常有用。

作为一个基本示例,如果您有一个显示50个网站及其favicon的页面,我们将在每次页面加载时查找favicon的URL。想象一下,这将大大增加页面加载时间。所以,通过从缓存中检索URL,将大大提高页面速度。

要缓存favicon,您可以使用在Favicon类上可用的cache方法。第一个参数接受一个Carbon\CarbonInterface作为缓存有效期。例如,要将https://ashallendesign.co.uk的favicon缓存1天,您的代码可能如下所示:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetch('https://ashallendesign.co.uk')->cache(now()->addDay());

默认情况下,该包将始终尝试从缓存中解析favicon,然后再尝试检索新版本。但是,如果您想禁用缓存并始终检索新版本,您可以使用以下方式的useCache方法:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::useCache(false)->fetch('https://ashallendesign.co.uk');

该包使用favicon-fetcher作为所有缓存键的前缀。如果您想更改此前缀,您可以通过更改favicon-fethcher配置文件中的cache.prefix字段来实现。例如,要将前缀更改为my-awesome-prefix,您可能需要更新您的配置文件如下:

return [

    // ...
        
    'cache' => [
        'prefix' => 'my-awesome-prefix',
    ]
            
    // ...

]

该包还提供了您可以使用fetchAll方法检索的favicon集合进行缓存的功能。您可以通过在FaviconCollection类上调用cache方法来完成此操作:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconCollection = Favicon::fetchAll('https://ashallendesign.co.uk')->cache(now()->addDay());

favicon类型

当尝试使用http驱动程序检索favicon时,我们可能能够确定favicon的类型(例如iconshortcut iconapple-touch-icon)。要获取favicon的类型,您可以如下使用getIconType方法:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconPath = Favicon::fetch('https://ashallendesign.co.uk')->getIconType();

此方法可以返回在Favicon类上定义的四个常量之一:TYPE_ICONTYPE_SHORTCUT_ICONTYPE_APPLE_TOUCH_ICONTYPE_ICON_UNKNOWN

您可以使用这些常量进行过滤等操作。例如,如果您想获取除了apple-touch-icon之外的所有图标,您可以这样做:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconCollection = Favicon::fetchAll('https://ashallendesign.co.uk');

$faviconCollection->filter(function ($favicon) {
    return $favicon->getIconType() !== Favicon::TYPE_APPLE_TOUCH_ICON;
});

favicon大小

当尝试使用http驱动程序检索favicon时,我们可能能够确定favicon的大小。要获取favicon的大小,您可以如下使用getIconSize方法:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$faviconSize = Favicon::fetch('https://ashallendesign.co.uk')->getIconSize();

假设图标是正方形的,因此只会返回一个整数。例如,如果favicon是16x16px,那么getIconSize方法将返回16。如果大小未知,将返回null

测试

要运行该软件包的单元测试,请运行以下命令

composer test

要为该软件包运行 Larastan,请运行以下命令

composer larastan

安全

如果您发现任何安全相关的问题,请直接通过mail@ashallendesign.co.uk联系我报告。

贡献

如果您想对该软件包进行任何修改或改进,请随意提交一个 pull request。

在提交您的 pull request 之前,请使用以下指南来贡献这个软件包

  • 为任何新添加的功能编写测试。如果您正在更新现有代码,请确保现有测试通过,并在需要时编写更多测试。
  • 遵循PSR-12编码标准。
  • 将所有 pull request 提交给 master 分支。

变更日志

查看变更日志以获取有关最新更改的更多信息。

升级

查看升级指南以获取有关如何更新此库到新版本的更多信息。

致谢

许可

MIT 许可证(MIT)。有关更多信息,请参阅许可文件

支持我

如果您觉得这个软件包很有用,请考虑购买Battle Ready Laravel以支持我的工作和努力。

每一次销售对我都有巨大的影响,这使我能够有更多的时间在开源项目和教程上工作。

为了表达衷心的感谢,您可以使用代码 BATTLE20 在书中获得 20% 的折扣。

👉 获取您的副本!

Battle Ready Laravel