Foreach loop, with tons of vars - php

I have a bunch of text in a database, which is id'ed by "grp" how would i get to bind each text to "example :
if($grp->$grp === '1') {
---> $text+$grp->$grp <--- = $grp->text
}
Is it possible to do a foreach & while loop, that binds the text to each "text1, text2 etc" ?
I've tried this way
foreach ($getgrouptxt as $grp) {
$grpnr = $grp->grp;
while ($grpnr < '63') {
$text+$grpnr = $grp->text;}
}
}
So basicly
Getting text from an array, using foreach looping through everyone of them
I want it to set the text var ($text"number") to
$grp-text, each time it hits a number until 62 is reached

+ is for numeric addition
You intend to append a number to a string, but you are using the numeric addition operator (+) instead of string concatenation operator (.). So, instead of $text+$grpnr you need $text.$grpnr
If you want to assign a value, the variable which will hold it is at the left-hand side of the assignment
If you want to store $text.$grpnr into $grp->text, then you need to invert the assignment:
$grp->text = $text.$grpnr;
If you want to use a dynamic variable name, then use {} around it
If $text.$grpnr should be a variable name and you intend to store $grp->text into it, then:
{$text.$grpnr} = $grp->text;
This will not work in PHP 5 though.
Beware comparing numbers as strings
'7' < '63'
is false, because PHP will do a textual comparison and '7' is behind '6' in the alphabet. If you want to use numeric comparisons, compare to 63 and convert $grpnr to a numeric type if it is textual.
Suggestion
According to the best of my understanding of your problem, you need something like
foreach ($getgrouptxt as $grp) {
$grpnr = $grp->grp;
while (((int)$grpnr) < 63) {
$grp->text = $text.$grpnr;
}
}

Related

Convert array of values into a single float value in PHP?

I have an array with these values (when the array is printed with print_r();
Array:
[0] => 66
[1] => 233
[2] => 204
[3] => 205
The values in hex are:
Array:
[0] => 0x42
[1] => 0xE9
[2] => 0xCC
[3] => 0xCD
What I'm looking to do is to turn this 4 byte array into a float value. If I use implode(); to turn the array into a value, it just combines the string into 66233204205 instead of 0x42E9CCCD which are not similar. Thus I can't use floatval(). PHP is new to me, and so is using string values instead of the actual bits, like I can in C.
What I'm thinking is to some how implode() it with the hex values, instead of those integer numbers, and then use floatval().
Any ideas guys?
EDIT:
Just so it's a little clearer, I should be obtaining 116.900 as the result
You have to do a simple math operation to concatenate hex values of the array one after the other. The algorithm would be like this:
Assign the first hex value of the array to a resultant variable, $concat in this case.
Use a for loop to loop through the array from 2nd element till nth element
In each iteration of the loop left shift 8 times the existing hex value of the resultant variable and place the new hex value in the least significant 8 bits of the resultant variable.
// Suppose $array is your original array
$concat = $array[0];
$count = count($array);
for($i = 1; $i < $count; $i++){
$concat = ($concat << 8) + $array[$i];
}
// display concatenated hex value: 42e9cccd
var_dump(dechex($concat));
// Now do your operation on the concatenated hex value
Here's a demo, https://eval.in/844793
Revised Answer with ....
Performing math with hex strings used to be a feature supported in PHP. Now with PHP 7, a hex string only represents a string of characters and no longer is recognized as containing a numeric value. If you attempt to do math with it, the result is zero. Consider the following code:
<?php
$arr = [66, 233, 204, 205];
$res = array_reduce( $arr, function($c,$i) {
$c.=dechex( $i );
return $c;
});
$temp = "0x" . $res; // 0x42e9cccd
var_dump($temp + 0);
See demo
This code attempts to provide the hex string a mathematical context by adding zero to the value contained in $temp. This code works until PHP 7 because the powers that be determined that hexstrings created more problems than they were worth; see this RFC and the Manual:"Hexadecimal strings are no longer considered numeric".
Concatenation, being a string operation, creates the example's hex string whose direct usage proves unwise in a math operation. A notice will be emitted (in PHP 7.1), complaining as follows:
Notice: A non well formed numeric value encountered
You may suppress displaying this notice, but the resulting sum will be zero in PHP 7. When the code functions correctly in PHP 5.6, the result of 1122618573 seems wrong, certainly far too large to cast as a float and obtain the value that the OP seeks.
... A Bona Fide Work-Around
<?php
$arr = [66, 233, 204, 205];
$res = array_reduce( $arr, function($c,$i) {
$c.=dechex( $i );
return $c;
});
$temp = "0x" . $res;
$int = filter_var( $temp, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX );
if (false === $int) {
throw new Exception("Invalid integer!");
}
$arr = (unpack('f', pack('i', $int )));
$f = array_pop($arr);
printf("%.3f",$f);
See demo
PHP will recognize the numeric hex string that array_reduce() yields if you use filter_var() with the indicated parameters. In this fashion, you may obtain an integer evaluating as 1122618573. The key thing rather than the integer's value is its binary bit pattern. Borrowing from the official answer here, the code needs to pack $int into a binary string, which it subsequently will unpack as a float -- almost. That result will be returned as an array with just one element. After popping off and capturing that element's float value, printf() displays 116.900.
This appends the values of the array to eachother (in hexadecimal). PHP's dechex() function.
http://php.net/dechex
dechex — Decimal to hexadecimal
$b = [66,233,204,205];
$a = dechex($b[0]);
for($x = 1; $x < count($b); $x++) {
$a = $a . dechex($b[$x]);
}
echo $a; // $a = 42e9cccd
You didn't specify if your array represents an integer, if is the integer part of the floating point value, or is the entire number represented in IEEE 754 format.
Anyway, I would suggest you to take a look at the "pack" function.
$value = pack('i', your_value);
HERE you can find the documentation: basically you have to provide the type you want to obtain, along with your value(s), of course.
Also PHP is NOT a strongly typed language, so you don't have to distinguish integer from floats, in this case. You can treat integer like floats, and viceversa. But if you want to be 100% sure, just do something like this:
$value = floatval(pack('i', your_value));
This is, of course, machine dependent, but I don't know of any machine running PHP that doesn't use IEEE 754 floats.

string being treated as a number when using if statement

i am using an if statement to compare 2 variables against each other, mainly in this case barcodes. i have noticed if they are leading with zeros and the only difference is one variable as more zeros at the beginning and the rest is the same its giving a true result as if they are the same, which in INT/NUMBER format that would be true, however i have checked and both are strings, so cant get my head around why it thinks "000005" and "0000005" are the same when they are not.
echo "<pre>";
$params['barcode_new'] = "0000005";
$params['barcode_old'] = "000005";
echo "var type : " .gettype($params['barcode_new']) ."<br>";
if ($params['barcode_old'] == $params['barcode_new']) {
echo "Master barcode already set to {$params['barcode_new']} <br>";
print_r($params);
}
Strings will be compared per character. Numbers by their value. So the strings differ and numbers will be equal. For type correctness use === to check if the values are identical and == if they are equal (e.g. numbers)
<?php
var_dump("0000005" == "000005");
var_dump("0000005" === "000005");
?>
bool(true)
bool(false)
Use Identical === operator instead. With === it will not convert the values and will match for the exact. Try with -
if ($params['barcode_old'] === $params['barcode_new']) {
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

Using Eval to perform if comparison of strings in PHP

I have some code that looks like this.
eval('$ruleTrue = '."{$value} {$operator} {$value2};");
I am pulling mostly numeric values from a database and comparing them with other numeric values. The operator comes from a database as well. Possible operators are <,>,==.
Well when comparing ints and floats this works perfectly. BUT when comparing strings it breaks. For instance..
WORKS:
5 > 4
$ruleTrue = true
Doesn't Work Right:
John-Adams == Alice
$ruleTrue = true <--- WHY? Because John is not == to Alice.
For some reason my $ruleTrue variable is being returned as true when comparing strings.
You're trying to evaluate this code:
$ruleTrue = John == Alice;
John and Alice aren't strings, they're undefined constants. You want to put quotes around them. But be careful, because if your users are able to edit those fields in your database, they could find a way of unquoting the strings and executing their own php code, which could be disastrous. Eval is very unsecure that way, and you probably shouldn't be using it.
The expression John-Adams == Alice parses somewhat like (John - Adams) == Alice. The left side is trying to subtract two strings (undefined constants are considered 'barewords', and are equal to a stringification of their names; John === 'John', for example), and in order to make sense of such an odd operation, PHP turns both strings into numbers. As integers, both strings have a value of 0, so the left side equates to 0.
An int.
Now, when PHP wants to compare with ==, it wants to coerce both sides into the same type. In this case, it's converting to int. Alice also converts to 0. Both sides being 0, they're "obviously" equal.
In order to prevent this from happening, you should probably put quotes around your values. You might also consider using the strict equals operator (===), unless you really want that type coercion magic.
Alternatively, if you have a known set of operators, you can eliminate eval and make this safer and more robust all around, by making a comparison function that has sub-functions for the operators. Like so:
function compare($value1, $op, $value2) {
static $known_ops = array(
'==' => function($a, $b) { return $a == $b; },
'!=' => function($a, $b) { return $a != $b; },
...
# you can even make up your own operators. For example, Perl's 'eq':
'eq' => function($a, $b) { return "$a" === "$b"; }
...
);
$func = $known_ops[$op];
return $func($value1, $value2);
}
...
$ruleTrue = compare($value, $operator, $value2);
Now you don't have to worry about your values. You do have to worry about $operator, but that's only an issue if you let a user input it without you validating it. In which case, you may want to throw an exception or something if $op wasn't in $known_ops, cause if you leave PHP to handle it, you'll likely get a fatal error when it tries to call null.
Make sure, if the value are strings, they are surrounded with "quotes"

PHP if condition with strings

I am trying to write would be a simple if condition.
function genderMatch($consumerid1, $consumerid2)
{
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1=$gender2)
echo 1;
return 1;
else
echo 0;
return 0;
}
The output of the getGender function is either a M or F. However, no matter what I do gender1 and gender2 are returned as the same. For example I get this output: MF1
I am currently at a loss, any suggestions?
if ($gender1 = $gender2)
assigns the value of $gender2 to $gender1 and proceeds if the result (i.e. the value of $gender2) evaluates to true (every non-empty string does). You want
if ($gender1 == $gender2)
By the way, the whole function could be written shorter, like this:
function genderMatch($cid1, $cid2) {
return getGender($cid1) == getGender($cid2);
}
You have to put two == for comparison. With only one, as you have right now, you are assigning the value to the first variable.
if($gender1=$gender2)
would become
if($gender1==$gender2)
this:
if($gender1=$gender2)
should be
if($gender1==$gender2)
notice the extra ='s sign. I think you might also need curly brackets for multiple lines of an if/else statement.
Your using the assignment operator = instead of comparsion operators == (equal) or === (identical).
Have a look at PHP operators.
You have some structural problems with your code as well as an assignment instead of a comparison.
Your code should look like this:
function genderMatch($consumerid1, $consumerid2){
$gender1=getGender($consumerid1);
$gender2=getGender($consumerid2);
echo $gender1;
echo $gender2;
if($gender1==$gender2){
echo 1;
return 1;
}else{
echo 0;
return 0;
}
}
Notice the double '=' signs in the if statement. This is a comparison. A single '=' is an assignment. Also, if you want to execute more than 1 line of code with an if/else, you need brackets.
You are using a single = which sets the variable, ie. the value of $gender1 is set to be the value of $gender2.
Use the === operator instead: if($gender1 === $gender2). It is usually a good idea to do strict comparisons rather than loose comparisons.
Read more about operators here: php.net
Another alternative is to use strcmp($gender1, $gender2) == 0. Using a comparer method/function is more common in languages where the string-datatype isn´t treated as a primary data-type, eg. C, Java, C#.

PHP: Check if 0?

I am using a class which returns me the value of a particular row and cell of an excel spreadsheet. To build up an array of one column I am counting the rows and then looping through that number with a for() loop and then using the $array[] = $value to set the incrementing array object's value.
This works great if none of the values in a cell are 0. The class returns me a number 0 so it's nothing to do with the class, I think it's the way I am looping through the rows and then assigning them to the array... I want to carry through the 0 value because I am creating graphs with the data afterwards, here is the code I have.
// Get Rainfall
$rainfall = array();
for($i=1;$i<=$count;$i++)
{
if($data->val($i,2) != 'Rainfall') // Check if not the column title
{
$rainfall[] = $data->val($i,2);
}
}
For your info $data is the excel spreadsheet object and the method $data->val(row,col) is what returns me the value. In this case I am getting data from column 2.
Screenshot of spreadsheet
Did you try an array_push() ?
array_push($rainfall, $data->val($i,2));
I would use a strict comparison with the not identical operator here instead of using the not equals operator:
if($data->val($i,2) !== 'Rainfall')
If $data->val($i,2) is an integer and you use == both sides will be cast to integers which would give you the result that all integers would work as you expect except for zero. Here's a summary of the difference between == and === when comparing the string "RainFall" with zero:
0 == "RainFall" : true
0 != "RainFall" : false
0 === "RainFall" : false
0 !== "RainFall" : true
I think that the array is treating the 0 like false, which could explain it not going into the array. Would something like this work (if you are using integers)?
(int)($data->val($i,2));
or
(float)($data->val($i,2);)
The problem lies in the if statement. You're trying to compare a string with an integer, which according to the PHP documentation will typecast both to integers.
If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.
You can read more here http://php.net/manual/en/language.operators.comparison.php.
Update: The if statement won't work in the case of 0 because (int)"Rainfall" will by typecasted into 0 by PHP causing the statement to be if (0 != 0) { ... }.
If $i represents the row number, why don't you start from 2 instead of 1?

Categories