Skip to content

Instantly share code, notes, and snippets.

@marcobrt
Last active October 1, 2021 21:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcobrt/72b2a3d1b0649c1bf738c9fc88f74ec0 to your computer and use it in GitHub Desktop.
Save marcobrt/72b2a3d1b0649c1bf738c9fc88f74ec0 to your computer and use it in GitHub Desktop.
Singleton PHP class used to keep an instance of gnparser open in streaming mode.
<?php
/*
* MIT License
*
* Copyright (c) 2021 Marco Bortolin
*/
class ScientificNameParser
{
protected static $parser = null;
protected $proc = null;
protected $pipes = null;
final protected function __construct() {}
function __destruct()
{
if(is_resource($this->proc)) {
fclose($this->pipes[0]);
fclose($this->pipes[1]);
if(is_resource($this->pipes[2])) {
fclose($this->pipes[2]);
}
proc_close($this->proc);
$this->proc = null;
}
}
static public function instance()
{
if(self::$parser === null) {
self::$parser = new self();
self::$parser->proc = @proc_open(GNPARSER." -s -f compact -d", [
0 => ["pipe", 'r'],
1 => ["pipe", 'w'],
2 => ['file', TMPDIR.'/gnparser-stderr.log', 'a'],
], self::$parser->pipes);
if(!is_resource(self::$parser->proc)) {
throw new Exception("Cannot create the child process");
}
stream_set_blocking(self::$parser->pipes[0], false);
stream_set_blocking(self::$parser->pipes[1], false);
}
return self::$parser;
}
function parse($scientific_name)
{
if(fwrite($this->pipes[0], $scientific_name . "\n" ) == 0) {
throw new Exception("Cannot write to stdin");
}
stream_select($rx=array($this->pipes[1]), $tx=null, $ex=null, null, null);
$stdout = stream_get_contents($this->pipes[1]);
if($stdout === false) {
throw new Exception("Cannot read from stdout");
}
return json_decode($stdout, true);
}
}
?>
@marcobrt
Copy link
Author

marcobrt commented Feb 22, 2021

You need to define:

  • GNPARSER with the path to the gnparser executable.
  • TMPDIR with the path to a directory where to put the stderr file.

Usage example:

<?php
$result = ScientificNameParser::instance()->parse( "Galium palustre L. subsp. palustre" );
print_r($result);
Array
(
    [parsed] => 1
    [quality] => 1
    [verbatim] => Galium palustre L. subsp. palustre
    [normalized] => Galium palustre L. subsp. palustre
    [canonical] => Array
        (
            [stemmed] => Galium palustr palustr
            [simple] => Galium palustre palustre
            [full] => Galium palustre subsp. palustre
        )

    [cardinality] => 3
    [details] => Array
        (
            [infraspecies] => Array
                (
                    [genus] => Galium
                    [species] => palustre
                    [authorship] => Array
                        (
                            [verbatim] => L.
                            [normalized] => L.
                            [authors] => Array
                                (
                                    [0] => L.
                                )

                            [originalAuth] => Array
                                (
                                    [authors] => Array
                                        (
                                            [0] => L.
                                        )

                                )

                        )

                    [infraspecies] => Array
                        (
                            [0] => Array
                                (
                                    [value] => palustre
                                    [rank] => subsp.
                                )

                        )

                )

        )

    [words] => Array
        (
            [0] => Array
                (
                    [verbatim] => Galium
                    [normalized] => Galium
                    [wordType] => GENUS
                    [start] => 0
                    [end] => 6
                )

            [1] => Array
                (
                    [verbatim] => palustre
                    [normalized] => palustre
                    [wordType] => SPECIES
                    [start] => 7
                    [end] => 15
                )

            [2] => Array
                (
                    [verbatim] => L.
                    [normalized] => L.
                    [wordType] => AUTHOR_WORD
                    [start] => 16
                    [end] => 18
                )

            [3] => Array
                (
                    [verbatim] => subsp.
                    [normalized] => subsp.
                    [wordType] => RANK
                    [start] => 19
                    [end] => 25
                )

            [4] => Array
                (
                    [verbatim] => palustre
                    [normalized] => palustre
                    [wordType] => INFRASPECIES
                    [start] => 26
                    [end] => 34
                )

        )

    [id] => 158e0431-9c8c-517c-a90e-68c8fe97ceef
    [parserVersion] => v1.0.9
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment