Jump to content

The nl_langinfo() Function


iwato

Recommended Posts

QUESTION: What must one do to obtain the values of the constants listed under the Parameters section of the nl_langinfo() function?My MACHINE: Apple MacOS 10.5.8 running with Apache and PHP Version 5.BACKGROUND: What I discovered so far.The following code retrieves the following PHP constant names and their respective values.The CODE

<?php	function returnConstants($prefix) {		foreach (get_defined_constants() as $key=>$value) {			if (substr($key,0,strlen($prefix))==$prefix) {				$dump[$key] = $value;			}		}		if(empty($dump)) {				return print "Error: No Constants found with prefix '". $prefix . "'";		} else {			return $dump;		}	}	$cnst_arr = returnConstants('LC');	var_dump($cnst_arr);?>

The VALUES

array(7) { ["LC_CTYPE"]=> int(2) ["LC_NUMERIC"]=> int(4) ["LC_TIME"]=> int(5) ["LC_COLLATE"]=> int(1) ["LC_MONETARY"]=> int(3) ["LC_ALL"]=> int(0) ["LC_MESSAGES"]=> int(6) }

Although ordered differently, the key-names of the above seven key-value pairs correspond exactly to the seven $category types given as parameter values for the setlocale() function.When one tries to discover what these constants imply for one's web-application via the setlocale() function, one discovers only that they correspond to the C or POSIX locale. As I do not understand UNIX, I am overwhelmed as a result.Plugging the LC constant category names into the nl_langinfo() function in an effort to obtain an array of values for the many options listed under the function's $item parameter results in an error message: "Warning: nl_langinfo() expects parameter 1 to be long, string given in ... on line 165."Plugging the LC constant category values into the nl_langinfo() function yields more tangible results but surely nothing close to the sought after list of options.The MORE TANGIBLE RESULTSarray(7) { ["LC_CTYPE"]=> string(8) "%m/%d/%y" ["LC_NUMERIC"]=> string(11) "%I:%M:%S %p" ["LC_TIME"]=> string(2) "AM" ["LC_COLLATE"]=> string(20) "%a %b %e %H:%M:%S %Y" ["LC_MONETARY"]=> string(8) "%H:%M:%S" ["LC_ALL"]=> string(8) "US-ASCII" ["LC_MESSAGES"]=> string(2) "PM" }Finally, the localeconv() function, although a move in the right direction, still does not yield the sought after list of values.Roddy

Link to comment
Share on other sites

If your question is how to get the values of the predefined constants for that function, you can just print them. e.g.:echo ABDAY_1;echo AM_STR;echo D_T_FMT;etc. You normally don't need the values of constants, that's why they use constants instead of arbitrary values. For the sake of compatibility with future versions it's much better to use the constants instead of their values. But, if you just want to see what values they currently hold, you can print them out. All of those constants will just be numbers, there's not a lot of meaning you can get from them.

Link to comment
Share on other sites

You normally don't need the values of constants, that's why they use constants instead of arbitrary values. For the sake of compatibility with future versions it's much better to use the constants instead of their values.
This makes good sense.
But, if you just want to see what values they currently hold, you can print them out. All of those constants will just be numbers, there's not a lot of meaning you can get from them.
This is, of course, less helpful, as I need both - the values of the constants and what they mean.Any further suggestion?Roddy
Link to comment
Share on other sites

There is no meaning other than what you see on the manual page.

AM_STR String for Ante meridian.
All that means is the value of that constant represents the AM string. It doesn't matter what the value is. It could be 0, it could be 100, it could be 93847394, whatever value the function wants to check for is the current value of the constant. This is why it is better to use constant names instead of the arbitrary values. This version, maybe the function assumes that the value 500 is AM_STR. Next version they might redefine that to be 501 instead, so if you're using values instead of constants then it's not going to be compatible with the next version. In programming these are called "magic numbers", and instead of using the arbitrary number values we define constants that have a meaningful name.
Link to comment
Share on other sites

There is no meaning other than what you see on the manual page.
Even if it were true -- something, by the way, that I find difficult to believe and am generally unable to verify for the reasons given below -- the information contained therein must be converted into meaningful formatting information. It is this latter and its relationship to the parameters and their values that I am seeking to discover.
When one tries to discover what these constants imply for one's web-application via the setlocale() function, one discovers only that they correspond to the C or POSIX locale. As I do not understand UNIX, I am overwhelmed as a result.Plugging the LC constant category names into the nl_langinfo() function in an effort to obtain an array of values for the many options listed under the function's $item parameter results in an error message: "Warning: nl_langinfo() expects parameter 1 to be long, string given in ... on line 165."Plugging the LC constant category values into the nl_langinfo() function yields more tangible results but surely nothing close to the sought after list of options.The MORE TANGIBLE RESULTSarray(7) { ["LC_CTYPE"]=> string(8) "%m/%d/%y" ["LC_NUMERIC"]=> string(11) "%I:%M:%S %p" ["LC_TIME"]=> string(2) "AM" ["LC_COLLATE"]=> string(20) "%a %b %e %H:%M:%S %Y" ["LC_MONETARY"]=> string(8) "%H:%M:%S" ["LC_ALL"]=> string(8) "US-ASCII" ["LC_MESSAGES"]=> string(2) "PM" }
Please, try again.Roddy
Link to comment
Share on other sites

The "more tangible results" seem like formats specific to the way the "C or POSIX locale" works. As you've said yourself, you are overwhelmed as a result... but that's just what these constants are for - so that you aren't. You just write the constant, and get the string you need. If you know how those "under the hood" formatting strings work (which I'd assume you can find at the referenced specs or in POSIX's source code), you can afford to also use the values directly instead of the constants. For all other purposes - don't.

Link to comment
Share on other sites

Please, try again.
What are you talking about "try again", did I get it wrong the first time? If you open the PHP source files and find this function implemented in C, you're going to see that even the function uses the constants, not the raw values. There is one section where it defines all of the constants, in one of the header files, and even these functions are going to use the constants. It really doesn't matter what the values are, because you're using the constants, and they're using the constants, and everyone is happy. You're looking for meaning where there is none. They could define the AM_STR constant to be the number 12345, or they could define it to be the string "OMG THEY WANT TO USE THE AM FORMAT STRING!!!!!!11!!". It really doesn't matter. If you think the value matters independent of the constant, then please explain why you think that. Again, the value has absolutely no meaning other than what the code gives it. The number 12345 doesn't mean anything unless the code is checking for 12345.
It is this latter and its relationship to the parameters and their values that I am seeking to discover.
Yeah, and it looks like this:
switch ($item){  case ABDAY_1:	// do something  break;  case ABDAY_2:	// do something  break;  case ABDAY_3:	// do something  break;  etc}

Link to comment
Share on other sites

It really doesn't matter what the values are, because you're using the constants, and they're using the constants, and everyone is happy. You're looking for meaning where there is none.
OK, it took me a while, but I now I can explain with great precision what I want to know.The below code generates the results that follow it. The results are a listing of all the values of all of the available constants for the LC_TIME Category of constants. I can now generate such a list of constant values for all of the other six POSIT categories including LC_MONETARY, LC_NUMERIC, LC_MESSAGES, LC_CTYPE, LC_COLLATE, and, of course, LC_ALL.QUESTION: Now, what I would like to know is where I can find an explanation for the meaning and implication of each of these integers for PHP in general and PHP functions and extensions in specific.
<?php	$lc_time = array(		'ABDAY_(1-7)' => 'Abbreviated name of n-th day of the week.',		'DAY_(1-7)' => 'Name of the n-th day of the week, eg. DAY_1 = Sunday.',		'ABMON_(1-12)' => 'Abbreviated name of the n-th month of the year.',		'MON_(1-12)' => 'Name of the n-th month of the year.',		'AM_STR' => 'String for Ante meridian.',		'PM_STR' => 'String for Post meridian.',		'D_T_FMT' => 'The string  used as the format string for to represent time and date.',		'D_FMT' => 'The string used as the format string for to represent date.',		'T_FMT' => 'The string  used as the format string for to represent time.',		'T_FMT_AMPM' => 'The string  used as the format string for to represent time in 12-hour format with ante/post meridian.',		'ERA' => 'Alternate era.',		'ERA_YEAR' => 'Year in alternate era format.',		'ERA_D_T_FMT' => 'Date and time in alternate era format.',		'ERA_D_FMT' => 'Date in alternate era format.',		'ERA_T_FMT' => 'Time in alternate era format.');	$lc_flip = array_flip($lc_time);	$lc_multival = preg_grep('/([A-Z]+_)(\(\d-)(\d+)\)/',$lc_flip);	$lc_unival = array_flip(array_values(preg_grep('/([A-Z]+_)(\(\d-)(\d+)\)/',$lc_flip, PREG_GREP_INVERT)));	while (list($key, $value) = each($lc_multival)) {		$lc_count[$value] = (int) preg_replace('/([A-Z]+_)(\(\d-)(\d+)\)/','$3',$value);		for($i=0; $i<$lc_count[$value]; $i++) {			$lc_expnd_val[$value][] = preg_replace('/([A-Z]+_)(\(\d-)(\d+)\)/','$1',$value) . ($i+1);		}	}	foreach ($lc_expnd_val as $key => $array) {		$array = array_flip($array);		$lc_expnd_val[$key] = $array;	}	$lc_time_expnd = array_merge($lc_expnd_val, $lc_unival);	function return_cnst_value(&$value, $key) {			$value = @constant($key);	}	array_walk_recursive($lc_time_expnd, 'return_cnst_value');	print_r($lc_time_expnd);?>

Array ( [ABDAY_(1-7)] => Array ( [ABDAY_1] => 14 [ABDAY_2] => 15 [ABDAY_3] => 16 [ABDAY_4] => 17 [ABDAY_5] => 18 [ABDAY_6] => 19 [ABDAY_7] => 20 ) [DAY_(1-7)] => Array ( [DAY_1] => 7 [DAY_2] => 8 [DAY_3] => 9 [DAY_4] => 10 [DAY_5] => 11 [DAY_6] => 12 [DAY_7] => 13 ) [ABMON_(1-12)] => Array ( [ABMON_1] => 33 [ABMON_2] => 34 [ABMON_3] => 35 [ABMON_4] => 36 [ABMON_5] => 37 [ABMON_6] => 38 [ABMON_7] => 39 [ABMON_8] => 40 [ABMON_9] => 41 [ABMON_10] => 42 [ABMON_11] => 43 [ABMON_12] => 44 ) [MON_(1-12)] => Array ( [MON_1] => 21 [MON_2] => 22 [MON_3] => 23 [MON_4] => 24 [MON_5] => 25 [MON_6] => 26 [MON_7] => 27 [MON_8] => 28 [MON_9] => 29 [MON_10] => 30 [MON_11] => 31 [MON_12] => 32 ) [AM_STR] => 5 [PM_STR] => 6 [D_T_FMT] => 1 [D_FMT] => 2 [T_FMT] => 3 [T_FMT_AMPM] => 4 [ERA] => 45 [ERA_YEAR] => [ERA_D_T_FMT] => 47 [ERA_D_FMT] => 46 [ERA_T_FMT] => 48)
Roddy
Link to comment
Share on other sites

The integers don't mean anything. They just provide a value that can later be checked by PHP or whatever program accepts those integers as inputs.Now, you may ask, why not use a string instead? Because integers are just 4 bytes in standard C, and a string is N+1 bytes, so using a number to label a string is simply more efficient for the majority of cases, memory wise... and CPU wise too I think.And why use a constant instead of the number itself? In case the number needs to be changed for whatever reason later on, plus you don't have to remember the number, but its descriptive name instead. Imagine if you had to do "23 40Hello World40 2" instead of "echo 'Hello World';".

Link to comment
Share on other sites

The integers don't mean anything. They just provide a value that can later be checked by PHP or whatever program accepts those integers as inputs.
So, why would PHP want to check a number that does not mean anything?This is neither credible, nor enlightening.Roddy
Link to comment
Share on other sites

It doesn't mean anything from a human's point of view. For programs (PHP included), it has an equivalent meaning of the constant that has it as value, so:

if ($input === ABDAY_1/*same as having 14 instead of the constant name*/) {//Apply meaning of ABDAY_1}

Link to comment
Share on other sites

if ($input === ABDAY_1/*same as having 14 instead of the constant name*/) {//Apply meaning of ABDAY_1}

This would be a could answer to the following question: What is a constant and how does one work?Unfortunately, it is not a question that I have ever asked and am certainly not asking in this thread.Using your example as a starting point, though, perhaps you could answer the following question:What effect would a change in the value of constant ABDAY_1 have on other PHP expressions and functions that depend on its value? Roddy
Link to comment
Share on other sites

What effect would a change in the value of constant ABDAY_1 have on other PHP expressions and functions that depend on its value?
The answer should be obvious. If they are working with the raw value instead of the constant, then they won't work right. If they are using the constant instead of the value, then for algorithms that only check the value (like the switch statement above), they will continue to work.Constants come in two varieties. One is just a "magic number", it's an otherwise meaningless number that just signifies a particular option or setting because that's how the code treats it. The other are bitmask constants, like the error reporting constants. Look at the values of these:http://www.php.net/manual/en/errorfunc.constants.phpWhy is there no constant with a value like 3, 5, 6, etc? The reason is because those are bitmask values, and so they are powers of 2 so that you can use binary math on them to combine options. E_ERROR has a value decimal of 1, or binary 0001, and E_WARNING has a decimal value of 2, or binary 0010. You can use a binary operator like | (or) to combine those, like this:E_ERROR | E_WARNING0001 | 00100011That happens to be decimal 3, so if you pass a value of 3 to error_reporting it will do both E_ERROR and E_WARNING. So bitmask constants have values which matter only insofar as allowing you to do binary operations with them, but other than a bitmask or some series of numerical constants that are also supposed to be able to be used with math operations, the constant's values don't have any meaning. If you think they do in fact have meaning, then offer some explanations as to why it's meaningful for any of those constants you printed out above to have the values they do. The only thing to notice is that no two constants have the same value, so that the algorithm can tell them apart.It may help you to think of it this way: suppose you are designing an algorithm that has many possible options. You need a way for people to specify which options they want. So, how do you set up your options? You could do strings, but sometimes strings lose their meaning over time. I'm sure you've created a CSS class at one point called something like "big_bold_text", but as the site progresses you change the styles so that the text is no longer bold or particularly big, so now you have a class name that doesn't describe what it does. That's the same reason why it's not a great idea to use strings for options. So, the next logical choice is numbers. You use the number 1 to signify whatever the first option is, 2 for another, etc. But, how do you make your algorithm easy to use? You don't want to expect yourself or others to remember that 45 is a particular option to do a particular thing, so you want to give them meaningful names. So, you define the constant ERA to equal 45, so people know that if they want to use the alternate era option, instead of having to remember 45 they just use the ERA constant.Hopefully that helps clarify how and why constants get used. In the future, you may get better answers quicker if you accept what people are saying (you can verify anything and everything in the source code for PHP), and try not to say things like this:
Even if it were true -- something, by the way, that I find difficult to believe
Please, try again.
This is neither credible, nor enlightening.
Here you are a beginner, you're just trying to learn about the nature of constants as they're used by most programmers. You're talking to me, someone with a degree in computer science who has been programming for over 10 years, and boen_robot, whose contributions here stand on their own, and it really sounds like you're saying that we don't know what we're talking about. With all due respect, the one who doesn't know what they're talking about is you. If you were perhaps a little more humble and willing to accept the answers given by people with a lot more experience than yourself, then perhaps the learning process would go easier for you.
Link to comment
Share on other sites

Well... that last paragraph was probably a little too harsh (I've never felt good when people approached me with that attitude), though I'll have to agree with the main point about you acceping what is being said, OR looking for proof/disproof yourself at the very sources (whether that's PHP sources, UNIX sources, documentations or something else). Some things simply can't be explained... sometimes, one has to try to do a similar thing on his/her own, and reach to the "aha" moment by doing so.We've been wrong before, and we'll probably be in the future too, but there will usually be a sample code piece to serve as proof... if you can find any code piece where constants don't serve as "magic number replacements", bitmasks, "commonly used values" or "read only variables"... if you can contact the programmers and ask them personally if there's meaning beyond the value serving as a "magic number replacement" or a bitmask, and they say there is... we'll be wrong then. But neither me or justsomeguy have witnessed such a thing, and we've never thought of constants as something with a deeper meaning.The idea behind a constant is similar to that of a variable, except it can only carry a scalar value (in PHP that is; constants in C and C++, AFAIK, can be any address in memory, with any data type there; I haven't tried, I may be wrong on that one), and the data can't be modified once it's set. In PHP at least, constants have a separate namespace from variables, so that's one more reason you may want to use a constant instead of a predefined variable. In other words, you can have $ABDAY_1, even though there is the ABDAY_1 constant. Also, constants can be used in any scope, whereas variables can only be used in the scope they are defined (see variables scope for details on that one, if you haven't already).

Link to comment
Share on other sites

Here you are a beginner, you're just trying to learn about the nature of constants as they're used by most programmers.
JSG, this has been your assumption since the beginning, or near beginning of this thread. It has never been my goal, however. Now, this does not mean that you have not added to my knowledge in this regard, for surely you have. It also does not mean that I am somehow ungrateful for your help. Unfortunately, however, my question has still not been answered, and I am merely asking for everyone's patience until it is has been answered, or I discover that it is a bad question whose answer is no longer worthy of anyone's further trouble.This said, as the thread progresses I do feel that I am coming ever nearer to the answer.Now, please consider the following two links: one is from my own already posted handiwork, and one is from The Open Group website.My recent post and this fairly recently discovered explanation found on the The Open Group website.My own handiwork simply results in a one-to-one correspondence between name and value of all of the available LC constants.The Open Group website on the other hand provide a rather lucid explanation of what these associated constants are likely to represent in more practical terms for a PHP user. My interest is in knowing how each of the LC constants -- not all LC constants, or even constants in general -- is related to the kinds of outcomes listed on The Open Group website. My goal is to understand how to manipulate and utilize the LC constants via various PHP methods such as setlocale and then utilize the constants to achieve specific outcomes via PHP functions such as those found in the MB string extension and elsewhere.Finally, I apologize, if the route to this discovery has become tortuous in any way. Believe me, I have suffered and learned from the investigation. This said, it was never intended to make others do the same.Roddy
Link to comment
Share on other sites

I'm not following, the C strftime function doesn't use constants. PHP has a version of that function as well but it doesn't use constants either:http://www.php.net/manual/en/function.strftime.phpThose functions simply take a string of characters that tell it how to format the date and time.

My goal is to understand how to manipulate and utilize the LC constants
You don't manipulate constants, their values never change. They are only used as named placeholders for specific values. It sounds like you're just looking for the list of constants and what they do like you see on the manual page for nl_langinfo, that's the only meaning you're going to find for those values.If you're looking for more meaning, you're going to need to study the source code for that function.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...