Trying to understand this entry in the php manual on debug_backtrace.
I don't understand what they mean by "this parameter is a bitmask for ...."
I have done web searches on bitmasks and my head is spinning round so I have decided I don't really want to learn the detail about it but just to know how I can supposed to add the options to that function.
Do I put in both options as in
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, DEBUG_BACKTRACE_IGNORE_ARGS)
if I want both and one of them if I only want that one?
Be aware that those 2 constants (DEBUG_BACKTRACE_PROVIDE_OBJECT, DEBUG_BACKTRACE_IGNORE_ARGS) are different in meaning. While DEBUG_BACKTRACE_PROVIDE_OBJECT provides an additional object when present, DEBUG_BACKTRACE_IGNORE_ARGS strips the args when present.
Since the most common use-case for these constants is to reduce memory usage, the way with least memory-consumption is:
debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
NOT
// false friend!
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
It overrides the default of DEBUG_BACKTRACE_PROVIDE_OBJECT and additionally ignores DEBUG_BACKTRACE_IGNORE_ARGS.
The constants will have values of 2^n in decimal, or (10)^n in binary. For example - 1, 10, 100, 1000, etc (in binary).
Say a=001, b=010, c=100:
You can do bitwise or on, for example, a and b. This will mean each bit will be 'turned on' if the same bit in either a or b is 'on'.
a | b == 011
This is a bitmask. The bitmask is checked for the inclusion of a by
bitmask & a != 0
Which is
011 & 001 == 001 != 0
However, because c is not in the bitmask:
bitmask & c == 011 & 100 == 0
So, to include both a and b in the bitmask, you use the binary or operator.
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
It means you combine options with the bitwise OR operator: |.
For example:
debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS);
For more details about bitmasks: http://en.wikipedia.org/wiki/Mask_(computing)
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Reference - What does this symbol mean in PHP?
I am trying to learn PHP and programming.
In the book I am studying there is something like:
$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE;
$flags is used for the split() method.
The first flag is: If this flag is set, only non-empty pieces will be returned by preg_split().
The second is: If this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well.
Why isn't he using && operator but the | ?
Can you please explain what | does actually?
As far as I know these are
&& is the logical AND whereas | is a bitwise operator.
a && b evalutes to true when both operands are evaluted to true. Since flags are almost always numbers greater than 1, this expression always evalutes to true.
How functions accepting bitmasks work
They specify constants
Note that these constants have to have powers of 2:
FLAG_INT1 = 1
FLAG_INT2 = 2
FLAG_INT3 = 4
FLAG_INT4 = 8
You call the function combining some flags
myFunction(FLAG_INT1 | FLAG_INT3)
This leads to a bitwise OR operation:
0001
OR 0100
=======
0101
A set bit (1) in one (or both) of the operands will lead to a set bit (1) in the result, too.
The function checks internally for each flag
This requires a bitwise AND operation:
0101
AND 0001 // check for FLAG_INT1
========
0001 // true
0101
AND 0010 // check for FLAG_INT2
========
0000 // false
0101
AND 0100 // check for FLAG_INT3
========
0100 // true
The bitwise AND required both operands to have a set bit (1) at position X in order to result in a set bit (1) in the result at position X.
Wikipedia has also a nice article about the common bitwise operators: http://en.wikipedia.org/wiki/Bitwise_operation
&& is the Logical "AND"
but the | is a bitwise
I would like to understand the following code from Zenphoto’s plugin:
$plugin_is_filter = 5|ADMIN_PLUGIN|THEME_PLUGIN;
The snippet was disjointed from context. It is just about the Idea behind it.
Are 5|ADMIN_PLUGIN|THEME_PLUGIN Permissions using bitwise?
When it is useful to use?
Thanks for any hint, links.
Bitfields are useful when you need to provide a set of boolean options in one variable. For example, PHP lets you set your error reporting like this:
error_reporting(E_ERROR | E_WARNING | E_PARSE);
In binary, those constants have these values:
E_ERROR 0001
E_WARNING 0010
E_PARSE 0100
If you OR a set of options like that together, you'll be able to express the settings in one field:
E_ERROR | E_WARNING | E_PARSE 0111
Then, you can check for an option being set using AND:
if ($option & E_ERROR === E_ERROR) {
// E_ERROR is set, do something
}
Yes, that is an example of bitwise OR.
You typically use bitwise operations when you're interested in packing multiple boolean flags into a single integer. Bitwise operators allow you to manipulate the individual bits of a byte, meaning an 8 bit byte can be used to store 8 distinct boolean values. It's a technique which was useful when using a whole 8 bit byte to store a single binary "yes" or "no" was considered wasteful.
Today, there is virtually no reason to ever prefer using this kind of bitpacking in PHP (especially with a magic number like that 5) over a simple configuration array. It is a technique which adds virtually nothing of value to PHP code, increasing complexity and decreasing maintainability for no real gain. I would be very skeptical of any new PHP code produced which makes use of bitwise flags in this way.
The variable $plugin_is_filter is being used to flag which plugins to load. Essentially, it is being treated like an array bits that correspond to an enumerated set plugins. For more information, see the links below.
This explains what ADMIN_PLUGIN and THEME_PLUGIN are.
Search the page for '$plugin_is_filter' to get a brief explanation of how to use this variable.
http://www.zenphoto.org/news/zenphoto-plugin-architecture
I hope this helps.
I noticed that some functions in PHP use flags as arguments. What makes them unique instead of plain string arguments? I'm asking since I want to use them on my own custom functions but am curious as to what the process is for doing so.
Edit: TO summarize, when is it best to create a custom function with flags and when is it not?
They are just constants which map to a number, e.g. SORT_NUMERIC (a constant used by sorting functions) is the integer 1.
Check out the examples for json_encode().
As you can see, each flag is 2n. This way, | can be used to specify multiple flags.
For example, suppose you want to use the flag JSON_FORCE_OBJECT (16 or 00010000) and JSON_PRETTY_PRINT (128 or 10000000).
The bitwise operator OR (|) will turn the bit on if either operand's bit is on...
JSON_FORCE_OBJECT | JSON_PRETTY_PRINT
...is internally....
00010000 | 1000000
...which is...
10010000
You can check it with...
var_dump(base_convert(JSON_PRETTY_PRINT | JSON_FORCE_OBJECT, 10, 2));
// string(8) "10010000"
CodePad.
This is how both flags can be set with bitwise operators.
Usually flags are integers that are consecutive powers of 2, so that each has one bit set to 1 and all others to 0. This way you can pass many binary values in a single integer using bit-wise operators. See this for more (and probably more accurate) information.
I read the following Stack Overflow questions, and I understand the differences between bitwise and logical.
Difference between & and && in PHP
Reference - What does this symbol mean in PHP?
However, none of them explains when I should use bitwise or logical.
When should I use bitwise operators rather than logical ones and vice versa?
In which situation do I need to compare bit by bit?
I am not asking about the differences, but I am asking the situation when you need to use bitwise operators.
Bitwise is useful for things in PHP just like anything else.
How about a value that can have multiple states turned on at the same time?
<?php
// since we're setting constant values in base10 we must progressively double
// them since bitwise operations work in base2. you'll see why when we output
// these as binary values below.
const STATE_FOO = 1;
const STATE_BAR = 2;
const STATE_FEZ = 4;
const STATE_BAZ = 8;
// show base2 values of the above constants
echo sprintf("STATE_FOO's base2 value is %08d\n", decbin(STATE_FOO));
echo sprintf("STATE_BAR's base2 value is %08d\n", decbin(STATE_BAR));
echo sprintf("STATE_FEZ's base2 value is %08d\n", decbin(STATE_FEZ));
echo sprintf("STATE_BAZ's base2 value is %08d\n\n", decbin(STATE_BAZ));
// set state to FOO and FEZ
$state = STATE_FOO | STATE_FEZ;
echo sprintf("base10 value of \$state is %s\n", $state);
echo sprintf("base2 value of \$state is %08d\n", decbin($state));
echo sprintf("Does \$state include FOO state? %s\n", (bool)($state & STATE_FOO));
echo sprintf("Does \$state include BAR state? %s\n", (bool)($state & STATE_BAR));
echo sprintf("Does \$state include FEZ state? %s\n", (bool)($state & STATE_FEZ));
echo sprintf("Does \$state include BAZ state? %s\n", (bool)($state & STATE_BAZ));
echo sprintf("Is state equivalent to FOO and FEZ states? %s\n", ($state == (STATE_FOO | STATE_FEZ)));
Output:
STATE_FOO's base2 value is 00000001
STATE_BAR's base2 value is 00000010
STATE_FEZ's base2 value is 00000100
STATE_BAZ's base2 value is 00001000
base10 value of $state is 5
base2 value of $state is 00000101
Does $state include FOO state? 1
Does $state include BAR state?
Does $state include FEZ state? 1
Does $state include BAZ state?
Is state equivalent to FOO and FEZ states? 1
Forget what is already in your head.
OK, now say you have some different roles: admin, user, and guest.
and some different permissions: read, write and delete
Let's create some bitmasks for permissions and roles. A bitmask is a sequence of bits that can be used to manipulate or read some kind of flags. As shown below:
// flags bitmasks
$read = 1; // 0001
$write = 2; // 0010
$delete = 4; // 0100
$admin = $read | $write | $delete; // 0001 | 0010 | 0100 => 0111
$user = $read | $write; // 0001 | 0010 => 0011
$guest = $read; // 0001 => 0001
Notice 1, 2, 4. This must be raised as double. Otherwise, it might give you some awkward results.
Forget about the things commented. Those are just sequence of bits (or bitmasks) for individual permissions and roles.
Now let's create a handy function which may be used to check a specific permission for a specific role.
function isAllowed($role, $permissison) {
return $role & $permissison ? true : false;
}
We are done. Let's check the $delete permission for all 3 roles:
var_dump(isAllowed($admin, $delete)); // bool(true)
var_dump(isAllowed($user, $delete)); // bool(false)
var_dump(isAllowed($guest, $delete)); // bool(false)
So why is bitwise operation? In a word, bitwise operation is more faster, concise and maintainable. Otherwise, using bitwise operation is always efficient for complex applications.
Bitwise | and & and logical || and && are totally different.
Bitwise operators perform operations on the bits of two numbers and return the result. That means it's not a yes or no thing. If they're being used in conditional statements, they're often used as part of logical comparisons. For example:
if ($x & 2 == 2) {
// The 2^1 bit is set in the number $x
}
Logical operators compare two (or more) conditions/expressions and return true or false. You use them most commonly in conditional statements, like if and while. For example:
if ($either_this || $or_this) {
// Either expression was true
}
Bitwise operators are specifically used in case of binary value representation.
echo '0110011010' & '0101001001';
//0100001000
Logical operators are most preferred for comparison and are a bit faster than bitwise operator in case of AND and XOR operations.
if(func1() && func2())
if func1() returns false it won't bother calling func2()
if(func1() & func2())
Will call both functions regardless of their returned values.
In most cases, you'll probably want to use logical operators. They're used for combining logical conditions, generally to control program flow, e.g. ($isAlive && $wantsToEat).
Bitwise operators are used when you want to perform operations on a bit-by-bit basis on the underlying binary representations of integers. e.g. (5 & 3) == 7. As others have suggested, there's usually not a lot of call for this in the sort of application that tends to get written in PHP (although there is in lower-level languages, like C).
Bitwise operators are useful when manipulating the bits of a number. Look here. Otherwise you should use the logical operators. Also the logical operators are short-circuited. For example, if you have a && b and a is false, b is not evaluated.
Disclaimer: I am coming from a Java background, but I guess in PHP it is the same.
They are two very different operators.
When you want two conditions to simultaneously be true, you use the logical &&. For example, I want to print out "happy birthday" only if the person's birthday is today && they have money in the account. This is used whenever we want to perform composition of two or more conditions, mostly in if statements and loop conditions (although not exclusively).
When you want to perform bitwise operations (which in day-to-day PHP programming is much more rare), you use the bitwise &. This is far more rare, and you might be performing bitwise masking (I doubt it though), so you might only want a result that both integers represent, in which case you can say newAttribute = attribute1 & attribute2;.
Well, asuming there is $x = (false && some_function());, here the value of $x will be set without calling the some_function() because the first value was FALSE.
But what if you needed to call that function anyway? Use $x = (false & some_function());.
In other words, the & uses MORE processing than the &&, just because && does not run through all the values to check them. If it found one value as false, it would return it, not looking at other values.
And in logical operations, use the && operator as it's used to return the logical operation value, where & is used to set a value and in an if statement it will always return true.
The variables values are listed below
$v['flag'] = 10
kPOSTAGE_HOME = 8
So what the heck does the following line do?!
if(($v['flag']&kPOSTAGE_HOME)==kPOSTAGE_HOME) {
//do something
}
& sets the bits set on both values. Some binary maths:
00001010 | 10
& 00001000 | 8
---------------
= 00001000 | 8
So 10&8 returns 8, and 8==8. Reason is to check whether a flag in that bit mask is set ...
It checks whether the bit-pattern in $v['flag'] has it's 3rd bit set.
And, for better readability, it can be simplified to the following:
if ( $v['flag'] & kPOSTAGE_HOME ) {
It's masking the '8' bit in the variable. The number '10' in base 10 == 1001 in binary, and 8 == 1000. So this means "does 1001 have the 1000" bit set?" The answer is 'yes'.
It checks whenever third bit is on in $v['flag'].
The & is "bitwise and" operator, binary of 8 is "00000100", therefore then you will do "bitwise and" all bits except the third will be zero, so in case third bit is on it will remains, therefore you have further check for equality.