如何在 Laravel 中获取网站图标

Laravel

在您的 Laravel 应用程序中,有时你可能希望显示来自另一个网站的图标。例如,你可以有一个指向要显示网站图标的外部站点的链接。

作为我的副项目 Mango Two 的一部分,我想这样做。 Mango Two 是一个开源的、隐私优先的 URL 缩短服务。 作为服务的一部分,我正在构建一个分析仪表板,用户可以在其中登录并查看他们过去创建的所有缩短的 URL。 我喜欢在每个 URL 的一侧添加网站图标以获得更好的视觉效果的想法。

当我开始阅读如何使用 PHP 为网站抓取图标时,我意识到这并不像我想象的那么简单。 例如,某些网站可能会在其网页的 <head> HTML 元素中使用“快捷方式图标”或“图标”<link> 元素来明确定义其网站图标的路径。 或者,某些网站可能只是将其 favicon 存储在 /favicon.ico 的默认路径中,并让浏览器自动找到它。

获取网站图标的另一种方法是使用外部服务,例如 Google Shared StuffFavicon Kit。 这两种服务都提供了非常易于使用的 API 来获取网站图标,并且看起来效果很好。 但是,由于 Mango 2 旨在保护隐私,我想减少它使用的外部服务的数量。

因此,我决定构建并发布一个名为“Favicon Fetcher”的 Laravel 包。 这是一个可以放入 Laravel 应用程序并用于获取 favicon 的包。 它支持多个驱动程序,还具有缓存和存储功能。

在本文中,我们将简要介绍如何使用 Favicon Fetcher 在 Laravel 应用程序中获取 favicon。

Laravel

我想你也会同意 Jess Pickup 在为软件包创建 logo 方面做得非常出色。 非常感谢,Jess!

安装

在开始之前,你需要确保你的应用程序的 PHP 版本为 8.0 以上和 Laravel 版本为 8 以上。

你可以通过 Composer 安装该软件包:

composer require ashallendesign/favicon-fetcher

你可以使用以下命令发布包的配置文件:

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

该软件包现在应该已安装完成并可以使用了。 你还应该有一个新的 config/favicon-fetcher.php 配置文件。

获取网站图标

现在你已经安装了这个软件包,你可以开始从不同的网站获取网站图标。

使用 fetch 方法

你可以使用 fetch 方法从网站获取网站图标,该方法将返回 AshAllenDesign\FaviconFetcher\Favicon 的实例:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

如果找不到该网站的网站图标,则将返回 null

使用 fetchOr 方法

如果你想在无法找到网站图标时提供一个使用的默认值,可以使用 fetchOr 方法。

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

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

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

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

$favicon = Favicon::fetchOr('https://ashallendesign.co.uk', function ($url) {
    // 在这样运行一些额外的逻辑

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

异常

如上所述,默认情况下,如果无法为 URL 找到网站图标,则 fetch 方法将返回 null。 但是,如果你希望抛出异常,可以使用 Favicon 门面的 throw 方法。 这意味着如果找不到网站图标,则会抛出AshAllenDesign\FaviconFetcher\Exceptions\FaviconNotFoundException

为了确保异常能够被抛出,你的代码可能像如下所示:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

驱动程序

不是每个项目都是一样的。 例如,在构建 Mango Two 时,我试图减少我正在使用的外部服务的数量。 但是,在其他项目上使用外部服务可能不是问题。 在我看来,这就是 Favicon Fetcher 的亮点,因为它提供了使用不同驱动程序从网站检索网站图标的功能。

可用的驱动程序

默认情况下,Favicon Fetcher 附带 4 个开箱即用的驱动程序:httpgoogle-shared-stufffavicon-kitunavatar

http 驱动程序通过尝试从返回的网页 HTML 中解析「图标」和「快捷方式图标」链接元素来获取网站图标。 如果找不到,它将尝试根据常用默认值猜测网站图标的 URL。

google-shared-stuff 驱动程序使用 Google Shared Stuff API 获取网站图标。

favicon-kit 驱动程序使用 Favicon Kit API 获取网站图标。

unavatar 驱动程序使用 Unavatar API 获取网站图标。

如何选择驱动程序

请务必记住,google-shared-stufffavicon-kit 驱动程序都与第三方 API 交互以检索网站图标。 因此,这意味着一些数据将共享给外部服务。

但是,http 驱动程序不使用任何外部服务,而是直接查询你尝试为其获取网站图标的网站。由于此软件包是新的,因此在尝试从网站获取网站图标时,http 驱动程序可能不会 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');

添加你自己的驱动程序

有时你可能想提供自定义逻辑来获取网站图标。 为此,你可以构建驱动程序并将其注册到包中以供使用。

首先,你需要创建自己的类并确保它实现了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');

如果你认为你的驱动程序对其他开发者有帮助,请随意在 GitHub 上的此软件包的仓库中创建项目。我非常乐意审查并考虑添加新的驱动程序来改进软件包。

存储网站图标

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

使用 store 方法

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

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

// $faviconPath 现在等同于 "/favicons/abc-123.ico"

如果你想使用不同的存储磁盘,可以将其作为可选的第二个参数传递给 store 方法。 例如,要将网站图标存储在 S3 上,如下所示:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

// $faviconPath 现在等同于 "/favicons/abc-123.ico"

使用 storeAs 方法

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

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

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

如果你想使用不同的存储磁盘,可以将其作为可选的第三个参数传递给 storeAs 方法。 例如,要将网站图标存储在 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"

缓存网站图标

除了能够存储网站图标外,该软件包还允许你缓存网站图标 URL。 如果你不想存储文件的本地副本并且想使用网站使用的网站图标的外部版本,这将非常有用。

作为一个基本示例,如果你有一个显示 50 个网站及其网站图标的页面,我们需要在每次页面加载时找到网站图标的 URL。 可以想象,这将大大增加页面加载时间。 因此,通过从缓存中检索 URL,它将大大提高页面速度。

要缓存网站图标,你可以使用 Favicon 类中提供的 cache 方法。 第一个参数接受 Carbon\CarbonInterface 作为缓存生命周期。例如,要将 https://ashallendesign.co.uk 的网站图标网址缓存 1 天,你的代码可能类似于:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

默认情况下,在尝试检索新版本之前,该软件包将始终尝试并从缓存中解析收藏夹图标。但是,如果你想禁用缓存并始终检索更新的版本, 则可以使用useCache 类似的方法:

use AshAllenDesign\FaviconFetcher\Facades\Favicon;

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

该软件包使用 favicon-fetcher 作为所有缓存键的前缀。 如果你想更改此操作,则可以通过更改 cache.prefix 字段中的 favicon-fethcher 配置文件。例如,要将前缀更改为 my-awesome-prefix,你可以这样更新配置文件:

return [

    // ...

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

    // ...

]

结论

希望这篇文章已经向你展示如何使用 Favicon Fetcher 软件包从 Laravel 应用程序中的网站获取 Favicons。

我将非常高兴如果你喜欢阅读这篇文章。同样,我很乐意接受任何改进的反馈。
继续建造很棒的东西! 🚀

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://laravel-news.com/favicon-fetcher

译文地址:https://learnku.com/laravel/t/67747

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!