What is the meaning of "|" in this PHP code? [duplicate] - php

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Reference - What does this symbol mean in PHP?
Below is the PHP code:
<?php
$a = $b['key'] | 0;
?>
Is it an operator?

The | is the bitwise OR operator.
Doing a bitwise OR with zero (| 0) doesn't make any sense though, as it will not flip any bits. Maybe the guy who wrote this was just a really bad programmer and tried to cast a string to an integer that way. He should have used a (string) cast instead!

Its bitwise OR, as defined here.
For example:
Bitwise Inclusive OR
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)

| is a bitwise OR function.
|| is a regular OR

It is the bitwise OR operator.
See here for more details:
http://php.net/manual/en/language.operators.bitwise.php

It is performing a bitwise OR operation.
It is possible the original author of the code meant to put another | in to make it a logical OR (||), because a bitwise OR with 0 will have no effect whatsoever on the output. Although even this makes no sense, he could have simply cast to an integer to get the same result.

| is a bitwise operator (http://php.net/manual/en/language.operators.bitwise.php)
| means "Bits that are set in either $b['key'] or 0 are set."
Because the second part is a zero though, it will return false only if $b['key'] is zero too.

Related

Bitwise Compressed Booleans - Toggling Specific Ones

Background
I have to store a number of true/false values in a database, and rather than make many columns, I instead am using a single int column, where I store all of the booleans, compressed using Bitwise operators.
Example:
Product 1 is certified as:
Lead Free - Yes
Gluton Free - No
Free Range - Yes
Organic - Yes
So in the DB, in the certs column, I'd compress 1, 0, 1, 1 into 13 (1 + 4 + 8).
I've written quick wrapper functions to compress and extract this information (change from int into boolean array and back).
Problem
I'm not sure of the best way to quickly add and remove values from this. Say I want to update the product to NOT be Free Range anymore. I can take the compressed int, minus 4. That works. Except what if it already wasn't Free Range? If I'm doing bulk operations, I need my function to only remove 4 from products that are currently certified Free Range, or the number gets messed up.
I have figured it out with a lengthy if statement, but it's not elegant. This works:
// $certs_current is the compressed int from the DB.
// $certs_new is a new integer. 4 would mean toggle "Free Range" to true. -4 would mean toggle it to false.
if ( $certs_current & abs($certs_new) ) {
if ( $certs_new < 0 ) {
$certs_current += $certs_new;
}
} else {
if ( $certs_new > 0 ) {
$certs_current += $certs_new;
}
}
This is a lot of if statements. I played around with the | operator, but it only works for adding positive numbers. Pass it a -4 and it breaks. And I can't figure out a nor operator.
Is there a better way to do this?
Edit:
In other words, is there an operator where: If I give it 13 and -4, it'll give me 9. But if I give it 9 and -4, it'll give 9? Or even just 13 and 4.
Edit 2
Adding in the | to my working logic, I've reduced the complexity and still have it working:
if ( $certs_new > 0 ) {
$certs_current = ( $certs_current | $certs_new );
} else {
if ( $certs_current & abs($certs_new) ) {
$certs_current += $certs_new;
}
}
Basically it says, if the new number is positive, then use the | operator to add it if it needs to be added. If it's negative, then we first check to see if we need to remove it, and if so, remove it. Which is the place where I think we can improve.
The | replaces an if statement, because it only adds the 4 if the 4 isn't already toggled to true (I realized that's a weird way to describe it).
But with the negative number, I still have a nested if statement, which is what I want to remove if possible.
You have the compressed value, so why don't you expand it before doing your operations?
$certs_temp = $certs_current
$is_organic = $certs_temp >= 8 && $certs_temp -= 8
$is_freerange = $certs_temp >= 4 && $certs_temp -= 4
$is_glutenfree = $certs_temp >= 2 && $certs_temp -= 2
$is_leadfree = $certs_temp >= 1 && $certs_temp -= 1
And then re-compress with the changed values (if indeed anything has changed).
I think you are asking for trouble if you try to operate directly on the stored integer, which actually represents 4 separate binary flags. Either represent each flag separately in the DB, or if you must have it stored as an integer, then decode it before applying changes or logic.
Answer
I figured it out. To toggle a boolean to false, we need to:
Reverse the primary compressed int from the DB, using ~ (13 in the example)
Add in the absolute value of the new int 4 ( not -4), using |.
Re-reverse the full int again, using ~.
So the final code, with only one if statement:
if ( $certs_new > 0 ) {
$certs = ( $certs | $certs_new );
} else {
$certs = ~( ~$certs | abs($certs_new) );
}
// 13 and 4 .... 13
// 13 and 2 .... 15
// 13 and -4 .... 9
// 13 and -2 .... 13

php synatax $b = (6 << 1); clarification [duplicate]

This question already has answers here:
PHP Operator <<
(5 answers)
Closed 7 years ago.
I am not clearly understand about the following code snippets.
$a = (5 << 0);
$b = (6 << 1);
echo $a|$b;
From php.net i knew that << operator use for shift left but not clear how it works and what is the uses of | operator.
Any explanation is highly appreciated.
Thank you
5 << 0 produces just 5, since no shift is done. 6 << 1 will shift the bits in 6 (110b) one to the left, which will produce 12 (1100b). So it is multiplying by two essentially.
The | operator is bitwise or, which operates on the bits of 5 (0101b) and 12 (1100b) producing 13 (1101b)
6 is '110' in binary. If you shift '110' once to the left you get '1100' which is 12
<< is the bitwise shift left operator:
00000110 is 6 in binary
6 << 1 means that each bit will be shifted 1 to the left:
00000110 (6)
becomes
00001100 (12)
so... 6 << 1 = 12
5 << 0 makes no difference as none of the bits are being shifted (5 << 0 = 5).
| is the bitwise 'or' operator:
5|12 makes:
00000101 | 00001100
This operator means if both bits are 0, the result will be 0, otherwise 1:
00000101 (5)
00001100 (12)
00001101 (13)
So 5|12 = 13
Hope you can find the solution here
Strange print behaviour in PHP?
for more information, you can check this link
Reference - What does this symbol mean in PHP?

How does this php code return odd numbers? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Understanding PHP's & operator
I was just looking at array_filter() function doc and they had the following code to return odd numbers...
<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
?>
Why does $var & 1 return odd number? how does that work?
& is bitwise and. It acts as a mask on the bits of $var. All odd numbers end with 1
no bit &1
1 001 1
2 010 0
3 011 1
4 100 0
5 101 1
6 110 0
7 111 1
You are using a bitwise function with always returns 1 when anded with an odd number.
A few examples:
11 = 3
01 = 1
----
01 = odd -- return 1 (true)
100 = 4
01 = 1
-----
000 = even -- return 0 (false)
One more:
10101 = 21
01 = 1
-------
00001 = odd -- return 1 (true)
That function return 1 if var is an odd number, 0 otherwise. "&" is the AND binary operator, so it considers the last binary digit of a number.
For example:
5 in binary is 101 -> 101 & 1 = 1 -> odd number.
8 in binary is 1000 -> 1000 & 1 = 0 -> even number.

What "|" character do? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Reference - What does this symbol mean in PHP?
I googled much for finding answer but i couldn't find any.
I saw in few free source codes that they use "|" sign to combine values or something. can someone enlighten what is different between "|" and "+"?
sample:
<?php
define('PERMISSION_DENIED', 0);
define('PERMISSION_READ', 1);
define('PERMISSION_ADD', 2);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 8);
$read_only = PERMISSION_READ;
$read_delete = PERMISSION_READ | PERMISSION_DELETE;
$full_rights = PERMISSION_DENIED | PERMISSION_READ | PERMISSION_ADD | PERMISSION_UPDATE | PERMISSION_DELETE;
$myrights = PERMISSION_READ;
$myrights |= PERMISSION_UPDATE;
?>
why not just:
<?php
define('PERMISSION_DENIED', 0);
define('PERMISSION_READ', 1);
define('PERMISSION_ADD', 2);
define('PERMISSION_UPDATE', 4);
define('PERMISSION_DELETE', 8);
$read_only = PERMISSION_READ;
$read_delete = PERMISSION_READ + PERMISSION_DELETE;
$full_rights = PERMISSION_DENIED + PERMISSION_READ + PERMISSION_ADD + PERMISSION_UPDATE + PERMISSION_DELETE;
$myrights = PERMISSION_READ;
$myrights += PERMISSION_UPDATE;
?>
it's the bitwise or operator, so you're operating with numbers in base 2 notation.
for example:
1000 | 0001 = 1001 ==> (8 | 1 = 9)
http://www.php.net/manual/en/language.operators.bitwise.php
In your code each permission is represented by one bit in a different position, I mean:
1 = 0001 = perm1
2 = 0010 = perm2
4 = 0100 = perm3
8 = 1000 = perm4
so doing or with those numbers gives you the number with all the permissions together. then if you wanna check if a permission is set you gotta do an and operation with the permission that you're checking, for example:
$user_perms = perm1 | perm3;
if ($user_perms & perm4) echo "user does not have this permission";
Okay, there is a difference. In order to see the difference you can just see how these numbers appear in binary:
0 = 00000000
1 = 00000001
2 = 00000010
4 = 00000100
8 = 00001000
As you can see, each of these numbers have only one bit set to one each in a different position.
Now, having a bitwise OR between them will make the result with one on each position as the operands:
00000010 |
00000100
----------
00000110
In this case it's the same as just adding the numbers.
0 | 0 = 0; 0 + 0 = 0
0 | 1 = 1 | 0 = 1 + 0 = 1
The difference comes here:
1 | 1 = 1
while
1 + 1 = 10 !!
The difference in this example is that bit-wise operator is faster because you just operate on the bits.
| is the bitwise OR (every bit of the result is 1 iff at least one of the corresponding bits in the inputs is 1). Using addition would work as well, but doesn't make it clear one is assembling a bitmask, and can lead to bugs, because
PERMISSION_READ + PERMISSION_READ != PERMISSION_READ
but
PERMISSION_READ | PERMISSION_READ == PERMISSION_READ
This is a bitwise OR operator.
You can find more information about it here : http://php.net/manual/en/language.operators.bitwise.php
Bitwise operators usual are good for soft encription methods

Php: What is the difference between | and || operator [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Reference - What does this symbol mean in PHP?
What is the difference between the | and || operators?
Just bumped into this line of code, and I was wondering what is the difference between these two case:
The person who did this do not remember what was the meaning, but it was important.
...
if ($condition1 | $condition2) {
...
...
if ($condition1 || $condition2) {
...
| = bitwise or
|| = boolean or
| is a bitwise or, || is a logical or. | operates on binary values whereas || operates on boolean ones.
E.g. 5 | 3 is 0101 OR 0011 which is 0111 which is 7, whereas True || False is True and False || False is False.
| is the bitwise-OR-operator while || is the logical-OR-operator.

Categories