如何在 Laravel 中获取网站 Favicon
发布日期:作者: Ashley Allen
在您的 Laravel 应用程序中,您可能需要在某些情况下显示来自其他网站的 Favicon。例如,您可能需要链接到一个外部网站,并希望与其 Favicon 一起显示。
在我的副项目 Mango Two 中,我想要做 exactly 的事。Mango Two 是一款开源、隐私优先的 URL 短链接服务。作为该服务的一部分,我正在构建一个分析仪表板,允许用户登录并查看他们过去创建的所有缩短的 URL。我喜欢在每个 URL 旁边添加 Favicon 来获得更好的视觉效果。
当我开始阅读有关如何使用 PHP 获取网站 Favicon 的信息时,我意识到这不像我想象的那样简单。例如,有些网站可能在网页的 <head>
HTML 元素中使用 "shortcut icon" 或 "icon" <link>
元素来明确定义其 Favicon 的路径。或者,一些网站可能将 Favicon 存储在 /favicon.ico
的默认路径中,并让浏览器自动找到它。
获取 Favicon 的另一种方法是使用外部服务,例如 Google Shared Stuff 或 Favicon Kit。这两种服务都提供了非常易于使用的 API 用于获取 Favicon,并且似乎运行良好。然而,由于 Mango Two 旨在成为隐私优先的服务,我想要减少它使用的外部服务的数量。
因此,我决定构建并发布一个名为 "Favicon Fetcher" 的 Laravel 包。这是一个可以添加到您的 Laravel 应用程序中的包,并用于获取 Favicon。它支持多种驱动程序,并具有缓存和存储功能。
在本文中,我们将简要了解如何在 Laravel 应用程序中使用 Favicon Fetcher 获取 Favicon。
我认为您也会同意 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
配置文件。
获取 Favicon
现在您已经安装了该包,您可以开始从不同的网站获取 Favicon 了。
fetch
方法
使用 要从网站获取 Favicon,您可以使用 fetch
方法,该方法将返回一个 AshAllenDesign\FaviconFetcher\Favicon
实例
use AshAllenDesign\FaviconFetcher\Facades\Favicon; $favicon = Favicon::fetch('https://ashallendesign.co.uk');
如果找不到网站的 Favicon,则将返回 null
。
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';});
异常
如上所述,默认情况下,如果找不到 URL 的 Favicon,fetch
方法将返回 null
。但是,如果您希望抛出异常,可以使用 Favicon
门面提供的 throw
方法。这意味着如果找不到 Favicon,将抛出 AshAllenDesign\FaviconFetcher\Exceptions\FaviconNotFoundException
。
要启用抛出异常,您的代码可能如下所示
use AshAllenDesign\FaviconFetcher\Facades\Favicon; $favicon = Favicon::throw()->fetch('https://ashallendesign.co.uk');
驱动程序
并非所有项目都相同。例如,在构建 Mango Two 时,我试图减少我使用的外部服务的数量。但是,在其他项目中使用外部服务可能不是问题。在我看来,这就是 Favicon Fetcher 闪耀的地方,因为它提供了使用不同的驱动程序从网站检索 Favicon 的功能。
可用的驱动程序
默认情况下,Favicon Fetcher 附带了 4 个开箱即用的驱动程序:http
、google-shared-stuff
、favicon-kit
和 unavatar
。
http
驱动程序通过尝试从网页返回的 HTML 中解析 "icon" 和 "shortcut icon" 链接元素来获取 Favicon。如果它找不到,它将尝试根据常见的默认值来猜测 Favicon 的 URL。
google-shared-stuff
驱动程序使用 Google Shared Stuff API 获取 Favicon。
favicon-kit
驱动程序使用 Favicon Kit API 获取 Favicon。
unavatar
驱动程序使用 Unavatar API 获取 Favicon。
如何选择驱动程序
重要的是要记住,google-shared-stuff
和 favicon-kit
驱动程序都与第三方 API 交互以检索 Favicon。因此,这意味着一些数据将被共享到外部服务。
但是,http
驱动程序不使用任何外部服务,而是直接查询您尝试获取其 Favicon 的网站。由于该包是新的,因此 http
驱动程序在尝试从网站获取 Favicon 时可能不完全准确。因此,从理论上讲,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
驱动程序获取网站图标,然后在找不到时回退到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());
现在您已注册自定义驱动程序,您可以像这样使用它来获取网站图标
use AshAllenDesign\FaviconFetcher\Facades\Favicon; $favicon = Favicon::driver('my-custom-driver') ->fetch('https://ashallendesign.co.uk');
如果您认为您的驱动程序对其他开发人员有用,请随时向 GitHub 上的包存储库发送 PR。我非常乐意审查并考虑添加新驱动程序以改进包。
存储网站图标
获取网站图标后,您可能希望将它们存储在您的文件系统中,以便将来无需再次获取它们。网站图标获取器提供两种用于存储网站图标的方法:store
和storeAs
。
store
使用如果您使用store
方法,将在存储之前自动为网站图标生成文件名。该方法的第一个参数接受一个字符串,它是存储网站图标的目录。您可以像这样使用默认文件系统磁盘存储网站图标
use AshAllenDesign\FaviconFetcher\Facades\Favicon; $faviconPath = Favicon::fetch('https://ashallendesign.co.uk')->store('favicons'); // $faviconPath is now equal to: "/favicons/abc-123.ico"
如果您想使用其他存储磁盘,可以将其作为可选的第二个参数传递给store
方法。例如,要在 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
方法,您将能够定义存储文件的名称。该方法的第一个参数接受一个字符串,它是存储网站图标的目录。第二个参数指定网站图标文件名(不包括文件扩展名)。您可以像这样使用默认文件系统磁盘存储网站图标
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
的网站图标 URL 缓存 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
作为所有缓存键的前缀。如果您想更改它,可以通过更改favicon-fethcher
配置文件中的cache.prefix
字段来做到这一点。例如,要将前缀更改为my-awesome-prefix
,您可以像这样更新配置文件
return [ // ... 'cache' => [ 'prefix' => 'my-awesome-prefix', ] // ... ]
结论
希望这篇文章能向您展示如何在 Laravel 应用程序中使用网站图标获取器包从网站获取网站图标。
如果您喜欢阅读这篇文章,我很乐意听到您的想法。同样,如果您有任何反馈意见来改进未来的文章,我也很乐意听到您的想法。
继续构建令人惊叹的东西!🚀