I have the following code:
$lang="de-AT";
$currency="3333";
$formatter = new NumberFormatter($lang, NumberFormatter::DECIMAL);
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, 2);
echo $formatter->format($currency);
can be run in here with copy/paste:online php (though I don't know the php version of this site)
which outputs: 3.333 and is exactly what I've expected.
But on my local host with PHP 7.0.20 and PHPUnit 6.2.1 the Unit test gives me as result: 3 333.
Any idea what's new or why?
The difference you see here for the locales de-AT:
3.333
and
3 333
is just that with a bare string comparison, there is a difference.
For written language, there is not. Both forms are correct in that locale and show the same number.
However, you'd like to configure that more explicitly, for that, command the number-formatter to use the dot '.' as thousands separator (instead of using the compiled in locale information):
$formatter->setSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL, '.');
Configuration Data
The underlying cause is that the PHP intl extension next to the actual code ships with language data (from the CLDR project) which consists of the formatting information in form of symbols and rules. That means, that the formatting can change (as you found out in your Phpunit test) even if the extension version is the same. Derived from your example:
Output for hhvm-3.15.4 - 3.19.0, 7.2.0alpha1
3.333
1.1.0
Output for 5.6.0 - 5.6.30, 7.0.0 - 7.1.6
3 333
1.1.0
The line which is causing the space instead of the dot is:
http://unicode.org/cldr/trac/browser/trunk/common/main/de_AT.xml#L120 (#13494)
The concrete change:
http://unicode.org/cldr/trac/changeset/11798/trunk/common/main/de_AT.xml
Previously the number group symbol was taken over from parent locale which has the dot.
That is in Changeset 11798 Timestamp: 07/13/15 12:38:02 (2 years ago) - Releases take time, so this is why you see this only in the later releases of the library.
I can only stress the point that this is configuration data.
Dealing with Configuration in (Unit-) Tests
In a unit-test you normally don't want to test for that. In a configuration test, you might want to test for that. Your Phpunit-test did reveal that the expectation you had so far is not matched any longer. So this might require either a code-change (that is to make your configuration expectation working again) or a change in the test, as you were testing locale specific configuration you might have not been what you were looking for.
From your question I can imagine that both is possible. In the end, the test reflects your expectation and might have revealed a hidden dependency, here the locale configuration data.
A fix could be as little as switching the locale to "de" instead of "de-AT": https://3v4l.org/hB15n
Output for 5.6.0 - 5.6.30, hhvm-3.15.4 - 3.19.0, 7.0.0 - 7.2.0alpha1
3.333
1.1.0
But keep in mind that this would also hide the underlying issue that you might have tested for the wrong thing. So better keep the failing test as a note to ask yourself about the expectations you had and if the code does for what you have it written for.
Related
I have followed the first answer solution of this question Installing PHP intl extension , so I have introduced in composer the line "ext-intl": "*", and run composer update (everything went smooth), but when I try to use within my controller $collator = locale_get_default(); I receive the following answer:
Error
Call to undefined function App\Http\Controllers\locale_get_default()
I do not know how to link my code to the ext-intl package that I have added to the composer configuration.
Thanks in advance for your help.
--
Thank you for your answer Sergio. I have realized that in the web server the php-intl is operative, so I only need to install it in my development environment (XAMPP over OSx: I will find out and come back). But now a new question has came out, thus:
Even in my web server (where php-intl is running) it seems that there is no effective link between the php and the Laravel levels. I have arrived to this conclusion (that surprises me), because if I make a change in the locale with php, it seems not to take place in Laravel Level. Example:
If I run the following (being the server configuration "en_US"):
setlocale(LC_ALL, "es_ES.utf8");
$collator = locale_get_default();
dd($collator);
the output is "es_ES", but if I run:
setlocale(LC_ALL, "es_ES.utf8");
dd(App::currentLocale());
the output is "en".
By the other side, if I run:
App::setLocale('es');
dd(App::currentLocale());
the output is "es". But if I run:
App::setLocale('es');
$collator = locale_get_default();
dd($collator);
the output is " en_US_POSIX ".
There is something that I am not understanding here! Do I have to change both levels at the same time when a localization change requested by the user takes place, so all functions related in both levels (PHP: uasort(), Laravel: Collection->sort(SORT_LOCALE_STRING)) work synchronized? This seems to be a potential source of inconsistencies! (?)
Thanks for the attention.
I've started using ApiGen with a Laravel project.
When I run it, I get the following error:
The class Illuminate\Auth\UserTrait is in use but has not been found in the defined sources.
Clearly it's complaining because Laravel's UserTrait isn't defined in the same file, but I obviously don't want to include my vendor/ directory and from the documentation I don't see how I can handle this. I want to use Jenkins to generate the documentation and because it returns a non-zero exit code it registers as an error, and thus breaks the build.
Here's my apigen.neon:
source:
- app
destination: docs
exclude:
- "*/tests/*.php"
- "*/database/*"
tree: true
sourceCode: true
todo: true
autocomplete:
# default
- classes
- constants
- functions
# other
- methods
- properties
- classconstants
title: My web app
Any idea how I can accomplish this?
EDIT 2019: I'm current owner of ApiGen.
ApiGen development stopped 3 years ago and it lacks of support and meaning. I do not recommend to use it
This should be fixed in last version (RC5 at the moment).
See: https://github.com/apigen/apigen/releases
For any further issues you can use Github issues to report them
As the title says:
Is there a Netbeans/PHPStorm plugin for writing/refactoring to PSR-compilant code ?
phphint.org does exactly that, but offers only an online-copy&paste-tool, not an IDE-integrated real time solution.
What exactly i'm searching for is:
"real time" PSR-code checking while typing
reformating/refactoring projects to fit PSR (1/2) coding guidelines (as far as possible)
In case you are wondering what i'm talking about:
PSR-1 Basic Coding Standard and PSR-2 Coding Style Guide are Coding Guidelines published by the big PHP guys.
For PhpStorm code formatting can be set to PSR1/PSR2 simply:
File -> Settings -> Code Style -> PHP -> Set From... -> Predefined Style -> PSR1/PSR2
Details are on the JetBrain's web site too.
And use Ctrl + Alt + L to reformat code.
Just have a look at Fabien Potenciers CS fixer at https://github.com/fabpot/PHP-CS-Fixer - I cannot tell you about the quality of the output, but as this seems to be a one time task, I don't think you'd need a plugin for this.
PHPStorm does format your code well to PSR standards by default, and it will also refactor stuff like missing curly braces for one-line if structures etc.
For the 2nd thing you ask, actually it's already built in Netbeans, you just have to configure it properly and hit ctrl+shift+F.
In addition to above answer - we need to use external tool in phpStorm
- step by step explanation to set it up on PHPStorm :
before we adding tool : we need to install php-cs-fixer globally
command line run : composer global require fabpot/php-cs-fixer
once Installed you can test it by entering
command line run : php-cs-fixer
should give something like this
once all good -
- go to PHPStorm
- go to settings
- External tools
- add new tool
add the following as per image below
Program : /Users/seramo/.composer/vendor/bin/php-cs-fixer (global path to php-cs-fixer- you can navigate and select right path for you )
Parameters: fix $FilePathRelativeToProjectRoot$ --level=psr2 ( this is command to execute on file )
Working Directory : $ProjectFileDir$
now save and apply.
in you file - menu -tools - External Tools - php-cs-fixer
running this should fix you file to PSR-2 Standards.
additionally, you can assign key to run this tool.
I'm trying to (in a parallel fashion, that's it, as we're still developing under PHP 5.2.x for our main applications) adapt our current applications to PHP 5.4.x (using Apache 2.4.2 with PHP 5.4.1 in our testing server) but I'm finding some warnings in our current applications when we run them in the testing server.
For example... we're using constant definition in our current applications with a function that detects the language and loads a language file containing the definitions like idiomas/lang.php, being lang a 2-digit language representation (es, us, de, and so on).
Inside each language file there's some definitions like this one:
define("IDIOMA_AF", "Afrikaans");
define("IDIOMA_AR", "العربية");
define("IDIOMA_BG", "български език");
So, when we want to output a given translated text, we do this:
<?php echo IDIOMA_AF; ?>
The message PHP 5.4.1 outputs when the application is thrown at it is the following:
Notice: Constant IDIOMA_AF already defined in D:\apache\htdocs\aplicacion\modulos\base\idiomas\es.php on line 34
Does anyone have the same problem? I would like to know a bit about your experiences, as it would be useful to know how to solve these problems. We're thinking on implementing a better system using gettext (which I think is more organized and easier to handle in the long run, but still...), although we would like to run our current applications for a while before upgrading them.
It means you are trying to define the constant twice (which is not allowed).
You could try:
if (!defined('IDIOMA_AF')) define('IDIOMA_AF', 'Afrikaans');
Or trace, and fix, why you are defining a constant twice anyway.
The function get_defined_constants() is also a useful debugging tool for issues like these.
Or, just ignore those errors: error_reporting(E_ALL & ~E_NOTICE);
I'm trying to setup and create new bundle with symfony2, but getting so much error almost every step.
I'm download symfony and run this command;
php bin/vendors install
> Installing/Updating swiftmailer
Cloning into /var/www/Symfony/vendor/swiftmailer...
...
...
...
[ErrorException]
Warning: constant(): Couldn't find constant Monolog\Logger::iNFO in /var/www/Symfony/vendor/symfony/src/Symfony/Bundle/MonologBundle/DependencyInjection/MonologExtension.php line 103
what is the problem? what should I do?
Error reason is Turkish system language. so in Turkish language "i" upper case "İ" and "I" lowercase "ı". I'm change my system language to English and problem solved.
write handler level uppercased to bypass this code
strtoupper($handler['level']))
for example
level: INFO
This sounds very very strange. The MonologExtension uses constant() at one point, and it does it like that:
constant('Monolog\Logger::'.strtoupper($handler['level']))
So basically, it uppercases the given level. Seeing the exception about ::iNFO not being found does not make sense, unless perhaps you have the mbstring extension enabled with the mbstring.func_overload option enabled as well.
Can you check if ini_get('mbstring.func_overload') returns 0/null? Otherwise that may be the cause. I really can't think of anything else.