|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2002-07-25 02:52 UTC] spud at nothingness dot org
This bug is related to others submitted that refer to _constants_ being affected by the locale change, but since this actually concerns a class name, I wanted to submit it separately. Pardon the error if it turns out to be one...
I'm internationalizing an app, which loads (include_once) a file called 'imc_Info.inc' containing two class definitions with their respective constructors:
class Info
and
class InfoOracle
In the course of loading the index page, I call
new InfoOracle()
and perform a query. This works fine in English, Spanish, French, and Greek. If I switch my app's locale to Turkish ('tr_TR'), however, I get a error:
Cannot instantiate non-existent class: ?acle in /var/www/html
(Yes, that ? appears in my logs). After searching for bug reports concerning Turkish, I noticed some closed/bogus reports that mentioned _case_, so I did some poking around.
Although my class constructor clearly reads
function InfoOracle() {
blah blah blah
}
PHP fails to acknowledge it. The get_declared_classes() function DOES return "info" and "infooracle" in its array though.
So I tried changing my call to
new infooracle(), simply lowercasing the whole name. That worked like a charm, in Turkish. I noticed in one of the other bug reports that Turkish contains no "I" in its character set, which _sort of_ explains the problem, but it still strikes me as a bug. Shouldn't class names remain unaffected by the current locale?
The following script demonstrates the problem. It generates the first output, then throws an error attempting the second.
---- SCRIPT ----
<?
// Set language to desired language
$g_lang = 'tr_TR';
putenv("LANG=$g_lang");
setlocale(LC_ALL, $g_lang);
class InfoBlob {
var $foo;
function InfoBlob() {
$this->foo = "Foo";
}
}
echo ('Instantiating an infoBlob with a lowercase i<br>');
$foobar = new infoBlob();
echo ($foobar->foo);
echo ('<br>Instantiating an InfoBlob with an uppercase I<br>');
$foobar = new InfoBlob();
echo ($foobar->foo);
?>
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Oct 26 18:00:01 2025 UTC |
I can confirm that this bug is still there... I'm testing with snapshot php5.2-200706031230 and get the following... Instantiating an infoBlob with a lowercase i<br>Foo<br>Instantiating an InfoBlob with an uppercase I<br> Fatal error: Class 'InfoBlob' not found in /root/php5.2-200706031230/test.php on line 18 Another simple script I have discovered that shows the same problem is... <?php echo setlocale(LC_ALL, "tr_TR.utf8")."\n"; foreach(get_declared_classes() as $class) { if(!class_exists($class)) echo "$class No Longer Exists!\n"; } ?> For this program I get the following output... [root@BlankFedora php5.2-200706031230]# sapi/cli/php ~/test2.php tr_TR.utf8 DOMImplementationList No Longer Exists! DOMImplementationSource No Longer Exists! DOMImplementation No Longer Exists! DOMProcessingInstruction No Longer Exists! RecursiveIteratorIterator No Longer Exists! IteratorIterator No Longer Exists! FilterIterator No Longer Exists! RecursiveFilterIterator No Longer Exists! ParentIterator No Longer Exists! LimitIterator No Longer Exists! CachingIterator No Longer Exists! RecursiveCachingIterator No Longer Exists! NoRewindIterator No Longer Exists! AppendIterator No Longer Exists! InfiniteIterator No Longer Exists! RegexIterator No Longer Exists! RecursiveRegexIterator No Longer Exists! EmptyIterator No Longer Exists! ArrayIterator No Longer Exists! RecursiveArrayIterator No Longer Exists! SplFileInfo No Longer Exists! DirectoryIterator No Longer Exists! RecursiveDirectoryIterator No Longer Exists! SimpleXMLIterator No Longer Exists! InvalidArgumentException No Longer Exists! __PHP_Incomplete_Class No Longer Exists! This does not just occur with tr_TR.utf8 it also occurs with the following locales... tr_CY.utf8, ku_TR.utf8 and az_AZ.utf8. ThanksWe are still getting this bug with PHP 5.2.3 PHP 5.2.3 (cli) (built: Feb 7 2008 06:40:06) As noted below, this function: <?php echo setlocale(LC_ALL, "tr_TR.utf8")."\n"; foreach(get_declared_classes() as $class) { if(!class_exists($class)) echo "$class No Longer Exists!\n"; } ?> Produces this error: tr_TR.utf8 DOMImplementationList No Longer Exists! DOMImplementationSource No Longer Exists! DOMImplementation No Longer Exists! DOMProcessingInstruction No Longer Exists! RecursiveIteratorIterator No Longer Exists! IteratorIterator No Longer Exists! FilterIterator No Longer Exists! RecursiveFilterIterator No Longer Exists! ParentIterator No Longer Exists! LimitIterator No Longer Exists! CachingIterator No Longer Exists! RecursiveCachingIterator No Longer Exists! NoRewindIterator No Longer Exists! AppendIterator No Longer Exists! InfiniteIterator No Longer Exists! RegexIterator No Longer Exists! RecursiveRegexIterator No Longer Exists! EmptyIterator No Longer Exists! ArrayIterator No Longer Exists! RecursiveArrayIterator No Longer Exists! SplFileInfo No Longer Exists! DirectoryIterator No Longer Exists! RecursiveDirectoryIterator No Longer Exists! SimpleXMLIterator No Longer Exists! InvalidArgumentException No Longer Exists! __PHP_Incomplete_Class No Longer Exists!This also occurs in function names: <?php echo setlocale(LC_ALL, 'tr_TR')."\n"; HI5(); function HI5() { echo "Five!\n";} ?> outputs: --- tr_TR Fatal error: Call to undefined function HI5() in... --- whereas the following works OK: <?php echo setlocale(LC_ALL, 'tr_TR')."\n"; function HI5() { echo "Five!\n";} HI5(); ?> outputs: --- tr_TR Five! --- using php-cli 5.2.6 on Ubuntu 8.10.EDIT: The code that I used to regenerate this bug as follows: foreach(get_declared_classes() as $class) { if(!class_exists($class)) echo "$class No Longer Exists!\n"; } This code does not produce errors anymore but method names are still giving this type of error. I'm using ImageMagick and its PHP extension, imagick, which gives the error "fatal: thumbnailImage() method not found", seems to be related with this bug. When I rewrite the method name as ...->thumbnailimage(), all works OK. So, the methods documented in http://www.php.net/manual/en/class.imagick.php which include "I" (capital i), it can not be used without replacing "I" with "i". (same errors occur with MagickWand class) Could you please fix this too?Why is this bug still not fixed? Not only class names are affected but function names aswell: <?php setlocale(LC_ALL, 'tr_TR.UTF-8'); class InfoBlob { public static function Intresting() { return 'is it not?'; } } echo (infoBlob::intresting()); // works lowercase i function and class. echo (infoBlob::Intresting()); // fails uppercase i function echo (InfoBlob::intresting()); // fails uppercase i class ?>The problem: <?php setlocale(LC_ALL, 'tr_TR.UTF-8'); echo strtolower('THIS IS JUST A TEST'); ?> output: thIs Is just a test So if it is using the same function internally to do the tolower on class names, it will not find them. A workarround would be use toupper instead of tolower in zend_internal namespace handling, despite the correct fix would be to use independent identifyers (??)I'm having a problem that I believe is a side-effect of this issue. I'm using the Twig extension in a project, and it uses the IteratorAggregate interface. When the locale is tr_TR, I get Fatal error: Interface 'IteratorAggregate' not found in .. When I do setlocale('en_US.UTF-8') or 'es_ES.UTF-8', everything works fine. I can provide the PHP compilation command line but the IteratorAggregate interface is built-in, so I assume it would be practically impossible to remove the interface during the compilation process.@nikic sorry, php version is 5.4.27 Yes, when I do not load Twig extension, this specific error goes away (only things dependent on Twig break, which has nothing to do with this bug). If these change anything: PHP is running in Apache as FastCGI; Zend Engine 2.4.0, ionCube loader v4.4.1. I can also provide a phpinfo() url if needed. Also note that the initial error reproduction code given by @spud @2002 does not reproduce. But the <?php echo setlocale(LC_ALL, "tr_TR.utf8")."\n"; foreach(get_declared_classes() as $class) { if(!class_exists($class)) echo "$class No Longer Exists!\n"; } ?> code reproduces, and I get tr_TR.utf8 DateInterval No Longer Exists! DOMImplementationList No Longer Exists! DOMImplementationSource No Longer Exists! DOMImplementation No Longer Exists! DOMProcessingInstruction No Longer Exists! InvalidArgumentException No Longer Exists! RecursiveIteratorIterator No Longer Exists! IteratorIterator No Longer Exists! FilterIterator No Longer Exists! RecursiveFilterIterator No Longer Exists! CallbackFilterIterator No Longer Exists! RecursiveCallbackFilterIterator No Longer Exists! ParentIterator No Longer Exists! LimitIterator No Longer Exists! CachingIterator No Longer Exists! RecursiveCachingIterator No Longer Exists! NoRewindIterator No Longer Exists! AppendIterator No Longer Exists! InfiniteIterator No Longer Exists! RegexIterator No Longer Exists! RecursiveRegexIterator No Longer Exists! EmptyIterator No Longer Exists! RecursiveTreeIterator No Longer Exists! ArrayIterator No Longer Exists! RecursiveArrayIterator No Longer Exists! SplFileInfo No Longer Exists! DirectoryIterator No Longer Exists! FilesystemIterator No Longer Exists! RecursiveDirectoryIterator No Longer Exists! GlobIterator No Longer Exists! MultipleIterator No Longer Exists! IntlDateFormatter No Longer Exists! __PHP_Incomplete_Class No Longer Exists! PharFileInfo No Longer Exists! SimpleXMLIterator No Longer Exists!Code to test is: $locales = array ( $language, $language.'.UTF-8', $language.'_'.strtoupper($language === 'en' ? 'us' : $language), $language.'_'.strtoupper($language === 'en' ? 'us' : $language).'.UTF-8' ); putenv('LC_ALL='.$locale); setlocale(LC_ALL, $locales); setlocale(LC_CTYPE, 'en_US'); bindtextdomain('messages', APPPATH.DS.'locale'); textdomain('messages'); bind_textdomain_codeset('messages', 'UTF-8'); In this example when you will set $language to "tr" everything is working but you must set LC_TYPE to en_US so in that moment we loose information about specific data from full locale data like currency, money formmating for that specific country. For me personally it's not problem but some of the coders that wish to use those features of local setting will be not able to do. Because they will be not able to follow the locale specification. Any ideas about to make it strait one like should be and have peaceful head? It is hard to isolate interpreter setting from global one? To always match php code in same way? This is code from my test of setting locale. And result are some if you will remove setting LC_TYPE to en_US you will end with wrong class names and than autoloader is not finding classes because they end with bad names where i is not i and everything is lowercased i names. I think you have same problem with this for long time and not provide proper architecture of interpreter to avoid change of crusial settings from php code level.fyi it seems that this bug has resurfaced in PHP 7.x PHP 7.0.27-0+deb9u1 (cli) (built: Jan 5 2018 13:51:52) ( NTS ) Copyright (c) 1997-2017 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies with Zend OPcache v7.0.27-0+deb9u1, Copyright (c) 1999-2017, by Zend TechnologiesHere is the env information I've tested this issue: root@debian9:~# lsb_release -da No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux testing (buster) Release: testing Codename: buster root@debian9:~# uname -a Linux debian9 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) x86_64 GNU/Linux root@debian9:~# php -v PHP 7.2.4-1+b2 (cli) (built: May 29 2018 02:53:13) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.4-1+b2, Copyright (c) 1999-2018, by Zend Technologies root@debian9:~# cat /etc/locale.gen | grep -v "#" en_US.UTF-8 UTF-8 tr_TR.UTF-8 UTF-8 root@debian9:~# apache2ctl -v Server version: Apache/2.4.33 (Debian) Server built: 2018-05-28T17:29:02Shame on you, PHP developers! I tested with PHP 7.2.4 and the problem still exists after 17 years!!! You ask for example code? Is it too hard for you just to try setlocale('tr_TR.UTF-8') followed by strtoupper('i'), strtolower('I') or ucfirst('i')?> Is it too hard for you just to try setlocale('tr_TR.UTF-8') followed by strtoupper('i'), strtolower('I') or ucfirst('i')? This has nothing to do with this bug report, which is about case-insensitive comparisons inside the engine. If there is an issue with strtoupper() behavior, please open a new bug report for it. I'm disabling further comments on this one.