Skip to content

Locale::getKeywords possible return values, and argument #5596

Description

@ekes

From manual page: https://php.net/locale.getkeywords


Before I make a PR for changes I thought I'd just run this as an issue, because I'm not 100% what should actually get returned.
The present documentation states array|false|null and null is only explained as when the max length has been exceeded.

In testing it for sure also returns null if there are no keywords in the locale. Which is based on a null return from the ICU function https://github.com/php/php-src/blob/c701c5781d02ffd140ef17f68853f8bb8007985b/ext/intl/locale/locale_methods.cpp#L747 https://skia.googlesource.com/external/github.com/unicode-org/icu/+/refs/heads/master/icu4c/source/common/unicode/uloc.h#943

Looking at the code it does look like it returns false on one occasion https://github.com/php/php-src/blob/c701c5781d02ffd140ef17f68853f8bb8007985b/ext/intl/locale/locale_methods.cpp#L777 but I can't work out what that is.

Additionally it uses the default locale if no locale is specified.

My working https://3v4l.org/nhDZW#veol

I'm hoping the 8.5 is just a quirk of 3v4l? The max length difference of 5.5.0 - 5.5.38, 5.6.0 - 5.6.27, 7.0.0 - 7.0.13 is interesting, but not important here I think. I guess the Locale class rather than procedural came later.

<?php

print "No keywords return: ";
var_dump(Locale::getKeywords('en'));
print "\nNo locale specified use the default, which doesn't usually have keywords. Returns: ";
var_dump(Locale::getKeywords(''));
print "\nBut it could, so worth mentioning the argument default. Returns: ";
Locale::setDefault('sl-Latn-IT-nedis@currency=EUR;collation=PHONEBOOK');
var_dump(Locale::getKeywords(''));
print "\nThe INTL_MAX_LOCALE_LEN is: " . INTL_MAX_LOCALE_LEN;
$long_locale = 'sl-Latn-IT-nedis@currency=EUR;collation=PHONEBOOK;calendar=islamic-umalqura;numbers=hansfin;foo=lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumip';
print "\nSo a string of " . strlen($long_locale) . " returns: ";
var_dump(Locale::getKeywords($long_locale));
$longer_locale = 'sl-Latn-IT-nedis@currency=EUR;collation=PHONEBOOK;calendar=islamic-umalqura;numbers=hansfin;foo=lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumips';
print "But a string of " . strlen($longer_locale) . " returns: ";
var_dump(Locale::getKeywords($longer_locale));
$keyword = 'lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumipslorumipsumsedutperspiciatisundeomnisistenatuserrorsit';
print "\nJust one keyword value with a max length longer than 100? (" . strlen($keyword) . ") Returns: ";
$keyword_locale = 'sl-Latn-IT-nedis@cfoo=' . $keyword;
var_dump(Locale::getKeywords($keyword_locale));
print "\nJust one keyword key with a max length longer than 100? (" . strlen($keyword) . ") Returns: ";
$keyword_locale = 'sl-Latn-IT-nedis@' . $keyword . '=foo';
var_dump(Locale::getKeywords($keyword_locale));

Output for 8.5.0 - 8.5.7

    No keywords return: 
    Fatal error: Uncaught Error: Class "Locale" not found in /in/nhDZW:4
    Stack trace:
    #0 {main}
      thrown in /in/nhDZW on line 4

    Process exited with code 255.

Output for 7.1.18 - 7.1.33, 7.2.6 - 7.2.34, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.34, 8.2.0 - 8.2.31, 8.3.0 - 8.3.31, 8.4.1 - 8.4.22

    No keywords return: NULL

    No locale specified use the default, which doesn't usually have keywords. Returns: NULL

    But it could, so worth mentioning the argument default. Returns: array(2) {
      ["collation"]=>
      string(9) "PHONEBOOK"
      ["currency"]=>
      string(3) "EUR"
    }

    The INTL_MAX_LOCALE_LEN is: 156
    So a string of 156 returns: array(5) {
      ["calendar"]=>
      string(16) "islamic-umalqura"
      ["collation"]=>
      string(9) "PHONEBOOK"
      ["currency"]=>
      string(3) "EUR"
      ["foo"]=>
      string(60) "lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumip"
      ["numbers"]=>
      string(7) "hansfin"
    }
    But a string of 157 returns: NULL

    Just one keyword value with a max length longer than 100? (114) Returns: array(1) {
      ["cfoo"]=>
      string(114) "lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumipslorumipsumsedutperspiciatisundeomnisistenatuserrorsit"
    }

    Just one keyword key with a max length longer than 100? (114) Returns: NULL

Output for 5.6.28 - 5.6.40, 7.0.14 - 7.0.33, 7.1.0 - 7.1.17, 7.2.0 - 7.2.5

    No keywords return: NULL

    No locale specified use the default, which doesn't usually have keywords. Returns: NULL

    But it could, so worth mentioning the argument default. Returns: array(2) {
      ["collation"]=>
      string(9) "PHONEBOOK"
      ["currency"]=>
      string(3) "EUR"
    }

    The INTL_MAX_LOCALE_LEN is: 80
    So a string of 156 returns: NULL
    But a string of 157 returns: NULL

    Just one keyword value with a max length longer than 100? (114) Returns: NULL

    Just one keyword key with a max length longer than 100? (114) Returns: NULL

Output for 5.5.0 - 5.5.38, 5.6.0 - 5.6.27, 7.0.0 - 7.0.13

    No keywords return: NULL

    No locale specified use the default, which doesn't usually have keywords. Returns: NULL

    But it could, so worth mentioning the argument default. Returns: array(2) {
      ["collation"]=>
      string(9) "PHONEBOOK"
      ["currency"]=>
      string(3) "EUR"
    }

    The INTL_MAX_LOCALE_LEN is: 80
    So a string of 156 returns: array(5) {
      ["calendar"]=>
      string(16) "islamic-umalqura"
      ["collation"]=>
      string(9) "PHONEBOOK"
      ["currency"]=>
      string(3) "EUR"
      ["foo"]=>
      string(60) "lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumip"
      ["numbers"]=>
      string(7) "hansfin"
    }
    But a string of 157 returns: array(5) {
      ["calendar"]=>
      string(16) "islamic-umalqura"
      ["collation"]=>
      string(9) "PHONEBOOK"
      ["currency"]=>
      string(3) "EUR"
      ["foo"]=>
      string(61) "lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumips"
      ["numbers"]=>
      string(7) "hansfin"
    }

    Just one keyword value with a max length longer than 100? (114) Returns: array(1) {
      ["cfoo"]=>
      string(114) "lorumipsumsedutperspiciatisundeomnisistenatuserrorsitlorumipslorumipsumsedutperspiciatisundeomnisistenatuserrorsit"
    }

    Just one keyword key with a max length longer than 100? (114) Returns: NULL

Output for 5.0.0 - 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.17, 5.3.0 - 5.3.29, 5.4.0 - 5.4.45

    No keywords return: 
    Fatal error: Class 'Locale' not found in /in/nhDZW on line 4

    Process exited with code 255.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions