php

Back Open Paginator
28.10.2025 13:34
blog (@blog@shkspr.mobi)

A Self-Hosted Favicon Proxy written in PHP

shkspr.mobi/blog/2025/10/a-sel

In theory, you should be able to get the base favicon of any domain by calling /favicon.ico - but the reality is somewhat more complex than that. Plenty of sites use a wide variety of semi-standardised images which are usually only discoverable from the site's HTML.

There are several services which allow you to get favicons based on a domain. But they all have their problems.

I want to show favicons next to specific links, but I don't want to expose my visitors to unnecessary tracking. How can I proxy these images so they are stored and served locally?

There are a few existing services. Some use Cloudflare workers or other cloud services, there are some local-first ones which are unmaintained. But nothing modern, self-hosted, and as easy to deploy as uploading a single PHP file.

So here's my attempt to make something which will preserve user privacy, be reasonably fast, and have moderately up-to-date icons, while remaining fast and efficient.

  • Table of Contents

  • Getting the domain
  • Getting the image
  • Getting the structure right
  • Preventing abuse
  • Putting it all together
  • Getting the domain

    Assuming the request comes in to https://proxy.example.com/?domain=bbc.co.uk

    PHP has a handy FILTER_VALIDATE_DOMAIN filter which will determine if the string is a domain.

    filter_var( $domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME );

    Dealing with IDNs

    Some domains contain non-ASCII characters - for example https://莎士比亚.org/ - not all favicon services support International Domain Names.

    Using the idn_to_ascii() function, it is possible to get the Punycode domain.

    $domain = idn_to_ascii("莎士比亚.org");

    Getting the image

    1. Check if the icon has previously been downloaded.
    2. Rotate randomly between a few different Favicon services.
    3. Download the icon.
    4. Save it somewhere.

    Getting the structure right

    I know from my work on OpenBenches that storing tens of thousands of files in a single directory can be problematic. So I'll store the retrieved favicon in: /tld/domain/subdomain/

    That will make it quick to see if an icon exists. I'll save the file with a filename based on the current timestamp. That will allow me to check if an icon is out of date, and will prevent people downloading the icons directly from me.

    Preventing abuse

    I don't want anyone but visitors to my site to be able to use this service. So I'll add a (weak) check to see if the request came from my domain.

    $referer = parse_url( $_SERVER["HTTP_REFERER"], PHP_URL_HOST );if ( $referer == "shkspr.mobi") {   …}

    Some browsers may not send referers for privacy reasons. So they won't see the favicons. But they probably wouldn't have seen the images loaded from a 3rd party service. So I'll serve a default image.

    Putting it all together

    You can grab the code from my personal git service.

    #favicon #HowTo #HTML #php




    Show Original Post


    28.10.2025 13:34
    JosephLeedy (@JosephLeedy@phpc.social)

    It appears that #Composer will finally support #Forgejo and #Codeberg repositories in the next release of version 2.9. 🙌🏽

    github.com/composer/composer/i

    #PHP




    Show Original Post


    28.10.2025 13:02
    qiita (@qiita@rss-mstdn.studiofreesia.com)

    EC-CUBEプラグイン実装で、気をつけること
    qiita.com/hirosaku21/items/21c

    #qiita #PHP #Plugin #EC_CUBE4




    Show Original Post


    28.10.2025 13:00
    phparch (@phparch@phparch.social)

    TODAY: @MikePageDev and @ccmiller2018 are talking with Estelle Gaits (Sylius Key Contributor, SyliusCon 2025 speaker & PHP/Symfony developer)
    Tune in at 8 PM GMT (timezones: phpa.me/alive-and-kicking-8PM) for PHP insights, open-source stories, and what's next in the Symfony ecosystem!
    youtube.com/phparch/live
    #PHP #Symfony #Sylius





    Show Original Post


    28.10.2025 12:39
    decompwlj (@decompwlj@mathstodon.xyz)

    A034856: a(n) = binomial(n+1, 2) + n - 1 = n*(n+3)/2 - 1

    3D graph, threejs - webGL ➡️ decompwlj.com/3Dgraph/A034856.
    3D graph Gen, threejs animation ➡️ decompwlj.com/3DgraphGen/A0348
    2D graph, first 500 terms ➡️ decompwlj.com/2Dgraph500terms/

    #decompwlj #math #mathematics #maths #sequence #OEIS #JavaScript #php #graph #3D #threejs #webGL #triangular #numbers #primes #PrimeNumbers #palindromes #animation #FundamentalTheoremOfArithmetic #sequences #NumberTheory #classification #integer #decomposition #number #theory #equation #graphs #sieve #fundamental #theorem #arithmetic #research





    Show Original Post


    28.10.2025 12:33
    decompwlj (@decompwlj@mathstodon.xyz)

    Decomposition into weight × level + jump of prime numbers:
    - a new classification of primes ➡️ decompwlj.com/primedecomp.php
    - in 3D - threejs - webGL ➡️ decompwlj.com/3Dgraph/Prime_nu

    #decompwlj #math #mathematics #maths #sequence #OEIS #JavaScript #php #graph #3D #threejs #webGL #triangular #numbers #primes #PrimeNumbers #palindromes #animation #FundamentalTheoremOfArithmetic #sequences #NumberTheory #classification #integer #decomposition #number #theory #equation #graphs #sieve #fundamental #theorem #arithmetic #research





    Show Original Post


    28.10.2025 12:32
    decompwlj (@decompwlj@mathstodon.xyz)

    A034838: Numbers k that are divisible by every digit of k

    3D graph, threejs - webGL ➡️ decompwlj.com/3Dgraph/A034838.
    3D graph Gen, threejs animation ➡️ decompwlj.com/3DgraphGen/A0348
    2D graph, first 500 terms ➡️ decompwlj.com/2Dgraph500terms/

    #decompwlj #math #mathematics #maths #sequence #OEIS #JavaScript #php #graph #3D #threejs #webGL #triangular #numbers #primes #PrimeNumbers #palindromes #animation #FundamentalTheoremOfArithmetic #sequences #NumberTheory #classification #integer #decomposition #number #theory #equation #graphs #sieve #fundamental #theorem #arithmetic #research





    Show Original Post


    28.10.2025 12:04
    ingewikkeld (@ingewikkeld@phpc.social)

    Optimaliseer de testefficiëntie van je team! Onze PHPUnit training leert je team hoe ze met dataproviders uitgebreide en grondige tests kunnen uitvoeren zonder dubbele code te schrijven. #PHP #PHPUnit #Efficiency





    Show Original Post


    28.10.2025 12:03
    nyamsprod (@nyamsprod@phpc.social)

    Periodic Reminder: you should spent as much time in your documentation than in your package development. I use #DDD for all my projects Documentation Driven Development 😎 . If I don't like the look of my examples in the documentation then chances are the public API is bad and needs adjustements. #PHP #OSS #library




    Show Original Post


    28.10.2025 11:53
    cooptilleuls (@cooptilleuls@mastodon.online)

    Au #ForumPHP 2025, notre coopérateur Albin a tenté de transformer 300 téléphones en pixels pour dessiner le logo #PHP dans la salle. Une expérience participative et interactive à base de PHP, Mercure, #FrankenPHP et @clevercloud : les-tilleuls.coop/blog/comment




    Show Original Post


    28.10.2025 11:27
    Temma (@Temma@phpc.social)

    Frameworks: Great Servants or Dangerous Masters?

    🔹 Frameworks = Structure & speed
    🔹 But too much reliance = Less control
    Are you coding freely… or inside their walls?

    🔗 LINK: phpwayoflife.com/fr/manifesto#

    #PHP #Framework #Coding #SoftwareArchitectur #WebDev #Tech





    Show Original Post


    28.10.2025 11:26
    pierstoval (@pierstoval@mastodon.social)

    I'm in a financial nightmare because I haven't found any job in months, and I've spent all the "safety net funds" I had.

    If I don't find a job in the next thirty days, I'm gonna bankrupt and be forced to either leave my family to work "in offices" far from home, or accept lower-range jobs and salaries that will barely be enough to feed my kids.
    As a reminder, my son has disabilities that need daily care I won't be able to give if I'm not at home.

    I'm requesting help 🙏




    Show Original Post


    1 ...353 354 355 356 357 358 359 360 361 362 363 ...526
    UP