1

I'm creating a CLI app in PHP and I want to open the help page in the default web browser. It's similar to what git does when you run git help <command> where it opens the relevant URL in the default browser.

On python there is the webbrowser.open function which takes care of it, but I couldn't find any package for PHP.

This is my approach so far but I'm not able to test it properly (i.e. Windows 7, Debian, MacOS, etc) so it is kind of hacky:

<?php

$uname = strtolower(php_uname());
$os    = (strpos($uname, "darwin") !== false) ? 'osx' : ((strpos($uname, "win") !== false) ? 'win32' : 'linux');
$end   = $os == 'win32' ? '' : '&';
$cmd1 = sprintf("%s $url $end", $os == 'win32' ? 'start ""' : ($os == 'osx' ? 'open' : 'xdg-open'));
pclose(popen($cmd1, "r"));

My questions are:

  • Is there a PHP library equivalent of python's webbrowser library that handles all OSes?

  • Is there another simpler approach to accomplishing it?

supersan
  • 5,671
  • 3
  • 45
  • 64
  • "start $url" in Windows ... have you tried it? I thought it would be "explorer $url" .... – Kevin_Kinsey Oct 10 '17 at 17:47
  • @Kevin_Kinsey yes tried it (it's also in the solution above), unfortunately it's not cross platform compatible. – supersan Oct 10 '17 at 18:41
  • My point was that "start $url" didn't even work on Windows here; on my system you have to call "explorer $url". 'Nix may be your real downfall though ... what if X isn't even running? – Kevin_Kinsey Oct 11 '17 at 17:04
  • hi, it's `start "" $url`.. there are double quotes after start for it to work. If X isn't running then a browser like `lynx` can do the job. – supersan Oct 12 '17 at 08:53

2 Answers2

1

Here are two small libraries that offer this functionality:

It looks to me like the latter is more fully featured.

pjcdawkins
  • 1,256
  • 1
  • 7
  • 8
0
function open_in_browser( string $url ): void {
    $url = filter_var( $url, FILTER_SANITIZE_URL );

    // We only open URLs.
    // We can also optionally allow FILTER_VALIDATE_IP as well.
    if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
        return;
    }

    // We only accept HTTP(s) protocol.
    if ( ! preg_match( '#^https?://#i', $url ) ) {
        return;
    }

    switch ( PHP_OS ) {
        case 'Darwin':
            // Mac.
            $command = 'open';
            $redirect_output = '2>/dev/null';
            break;
        case 'WINNT':
            // Windows. The double quotes are required, as the first parameter of "start" is the title, which we leave empty.
            $command = 'start ""';
            $redirect_output = '2> nul';
            break;
        default:
            // Portable command across most Linux distros.
            $command = 'xdg-open';
            $redirect_output = '2>/dev/null';
    }

    @exec( sprintf( '%s %s %s', $command, escapeshellarg( $url ), $redirect_output ) );  
}

Usage:

open_in_browser( 'https://example.com' );

Behavior in different OS:

  • Manjaro Linux with KDE and Brave browser: Works.
  • Windows 11: Works.
  • Mac: Can someone please confirm this works in Mac?
  • Ubuntu: Can someone please confirm this works in Ubuntu?
  • Other linux distros?

Additionally, if you want to be sure that the user will be able to visit the URL, you can also echo it before the exec:

echo "Please open this URL in the browser, it it hasn't opened already: $url\n";

In all approaches above, the operating systems will try to "execute" the URL. Since it has the HTTP(s) protocol, the default browser will be assigned to handle it and will open the URL.

This function does a good job at sanitizing, but better be safe than sorry. Since it executes a command in the host machine, you have to be extra careful. Do not pass a $url that you don't control.

Lucas Bustamante
  • 15,821
  • 7
  • 92
  • 86