Asked  7 Months ago    Answers:  5   Viewed   30 times

What are the ? and : operators in PHP?

For example:

(($request_type == 'SSL') ? HTTPS_SERVER : HTTP_SERVER)

 Answers

66

This is the conditional operator.

$x ? $y : $z

means "if $x is true, then use $y; otherwise use $z".

It also has a short form.

$x ?: $z

means "if $x is true, then use $x; otherwise use $z".

People will tell you that ?: is "the ternary operator". This is wrong. ?: is a ternary operator, which means that it has three operands. People wind up thinking its name is "the ternary operator" because it's often the only ternary operator a given language has.

Tuesday, June 1, 2021
 
Silfverstrom
answered 7 Months ago
75

It's the Ternary Operator.

Basic usage is something like

$foo = (if this expressions returns true) ? (assign this value to $foo) : (otherwise, assign this value to $foo)

It can be used for more than assignment though, it looks like other examples are cropping up below.

I think the reason you see this in a lot of modern, OO style PHP is that without static typing you end up needing to be paranoid about the types in any particular variable, and a one line ternary is less cluttered than a 7 line if/else conditional.

Also, in deference to the comments and truth in naming, read all about the ternary operators in computer science.

Wednesday, March 31, 2021
 
dmp
answered 9 Months ago
dmp
82

The bit shifting operators do exactly what their name implies. They shift bits. Here's a brief (or not-so-brief) introduction to the different shift operators.

The Operators

  • >> is the arithmetic (or signed) right shift operator.
  • >>> is the logical (or unsigned) right shift operator.
  • << is the left shift operator, and meets the needs of both logical and arithmetic shifts.

All of these operators can be applied to integer values (int, long, possibly short and byte or char). In some languages, applying the shift operators to any datatype smaller than int automatically resizes the operand to be an int.

Note that <<< is not an operator, because it would be redundant.

Also note that C and C++ do not distinguish between the right shift operators. They provide only the >> operator, and the right-shifting behavior is implementation defined for signed types. The rest of the answer uses the C# / Java operators.

(In all mainstream C and C++ implementations including GCC and Clang/LLVM, >> on signed types is arithmetic. Some code assumes this, but it isn't something the standard guarantees. It's not undefined, though; the standard requires implementations to define it one way or another. However, left shifts of negative signed numbers is undefined behaviour (signed integer overflow). So unless you need arithmetic right shift, it's usually a good idea to do your bit-shifting with unsigned types.)


Left shift (<<)

Integers are stored, in memory, as a series of bits. For example, the number 6 stored as a 32-bit int would be:

00000000 00000000 00000000 00000110

Shifting this bit pattern to the left one position (6 << 1) would result in the number 12:

00000000 00000000 00000000 00001100

As you can see, the digits have shifted to the left by one position, and the last digit on the right is filled with a zero. You might also note that shifting left is equivalent to multiplication by powers of 2. So 6 << 1 is equivalent to 6 * 2, and 6 << 3 is equivalent to 6 * 8. A good optimizing compiler will replace multiplications with shifts when possible.

Non-circular shifting

Please note that these are not circular shifts. Shifting this value to the left by one position (3,758,096,384 << 1):

11100000 00000000 00000000 00000000

results in 3,221,225,472:

11000000 00000000 00000000 00000000

The digit that gets shifted "off the end" is lost. It does not wrap around.


Logical right shift (>>>)

A logical right shift is the converse to the left shift. Rather than moving bits to the left, they simply move to the right. For example, shifting the number 12:

00000000 00000000 00000000 00001100

to the right by one position (12 >>> 1) will get back our original 6:

00000000 00000000 00000000 00000110

So we see that shifting to the right is equivalent to division by powers of 2.

Lost bits are gone

However, a shift cannot reclaim "lost" bits. For example, if we shift this pattern:

00111000 00000000 00000000 00000110

to the left 4 positions (939,524,102 << 4), we get 2,147,483,744:

10000000 00000000 00000000 01100000

and then shifting back ((939,524,102 << 4) >>> 4) we get 134,217,734:

00001000 00000000 00000000 00000110

We cannot get back our original value once we have lost bits.


Arithmetic right shift (>>)

The arithmetic right shift is exactly like the logical right shift, except instead of padding with zero, it pads with the most significant bit. This is because the most significant bit is the sign bit, or the bit that distinguishes positive and negative numbers. By padding with the most significant bit, the arithmetic right shift is sign-preserving.

For example, if we interpret this bit pattern as a negative number:

10000000 00000000 00000000 01100000

we have the number -2,147,483,552. Shifting this to the right 4 positions with the arithmetic shift (-2,147,483,552 >> 4) would give us:

11111000 00000000 00000000 00000110

or the number -134,217,722.

So we see that we have preserved the sign of our negative numbers by using the arithmetic right shift, rather than the logical right shift. And once again, we see that we are performing division by powers of 2.

Tuesday, June 1, 2021
 
Gigamegs
answered 7 Months ago
33

Traditionally, a Doctype, or Document Type Declaration associates the document with a Document Type Definition.

The Document Type Definition is a standard for a specific XML or SGML document. XML and SGML themselves doesn't have much of a schema or a very specific set of rules aside from how tags and attributes work in general. You can think of a DTD a description of the rules for a particular kind of document (like HTML, SVG or MathML). They say what tags are allowed where (e.g. that an html element must contain exactly one head element followed by exactly one body element).

There are alternatives to DTDs such as XML Schemas that are more commonly used today.

Browsers, however, do not use DTDs at all. They read the Doctype to determine the rendering mode, but the rules for parsing the document are entirely baked into the browser.

This is why HTML 5 has a Doctype (to determine the rendering mode) but not DTD.

Rendering Modes

Early web browsers were very buggy. When new versions were released they had to maintain compatibility with their predecessors and rivals. This made it very hard to fix bugs because websites were built that depended on them.

To resolve this, modern browsers have different rendering modes (standards mode, for rendering your document and css according to standards, and quirks mode, wherein the browser emulates the bugs of earlier browsers, and almost standards mode which sits between the two).

Choosing a Doctype

There are two factors to consider when selecting a Doctype:

  • Does it trigger standards mode? (For new pages it should, times when you need to be compatible with browsers which don't support standards mode are very rare today).
  • Does it support the features I need?

Generally this means you should use HTML 5. It is the current standard and best reflects how browsers actually work:

<!DOCTYPE html>

Failing that. Strict doctypes avoid most features that should be handled with CSS.

When writing in XHTML 1.0, this Doctype is common:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

More obsolete features are available via:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">

When writing in HTML 4.01, this one is common instead:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

With the obsolete features being in

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

and

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">

Note that most of the above have variations (e.g. you can omit the URL and rely on the public identifier) which have implications for the support of standards mode. This article includes an extensive list.

Debate on Strict versus Transitional Doctypes

(Note that the following is much, must less true in 2021 than it was in 2008)

Standards evangelists have called for web developers to stop using the Transitional Doctype on new pages and instead use Strict. Again, this is a case where the theory and the practice have some difficulties being reconciled. The original hope of the transitional Doctype was to provide a halfway house for transitioning legacy websites toward standards-compliance. With transitional doctypes, the restriction on elements and attributes is literally "less strict", so developers would be able to get their work running under standards mode sooner, and phase out the outstanding differences over time.

Controversy exists because it isn't always quite so simple for a developer change the Doctype in an enterprise environment. Freelance developers and makers of small- or medium- sized websites may often have an easier time determining their Doctype and making this transition. In an enterprise production environment for a highly-demanded web-based service, there are inherently more complicated dependencies on legacy systems and 3rd party code products, which themselves may be on a roadmap for removal or redesign, but the execution of such changes must be done methodically and incrementally.

Helpful Tools

The W3C (World Wide Web Consortium) is a group which plays an active role in defining these kinds of standards. They maintain a helpful online tool at http://validator.w3.org/ for verifying and validating documents against their standards. There are many other 3rd party tools and browser extensions with similar functionality.

Wednesday, June 9, 2021
 
Webroots
answered 6 Months ago
93

Conditional operators are intentionally succinct and especially useful for assignments:

var a = x ? 1 : 2;

Using them to conditionally run functions, while possible, should, for the sake of readability be done using IF/ELSE statements:

// This is possible but IMO not best practice:
X ? doSomething() : doSomethingElse();

While long-winded, most of the time, this is the better solution:

if (X) {
    doSomething();
} else {
    doSomethingElse();
}

One notable benefit to the IF/ELSE structure is that you can add additional tasks under each condition with minimal hassle.

Your last snippet is also possible but it looks somewhat long-winded and, again, might be better suited to a more conventional logical structure; like an IF/ELSE block.

That said, a conditional operator can still be readable, e.g.

(something && somethingElse > 2) ?
   doSomeLongFunctionName()
   : doSomeOtherLongFunctionName();

In the end, like many things, it's down to personal preference. Always remember that the code you're writing is not just for you; other developers might have to wade through it in the future; try and make it as readable as possible.

Saturday, September 18, 2021
 
PeterTheLobster
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share