Structure

Use parentheses when instantiating classes regardless of the number of arguments the constructor has.

Declare class properties before methods.

Declare public methods first, then protected ones and finally private ones.
The exceptions (when using PHPUnit) to this rule are the class constructor and the setUp and tearDown methods of PHPUnit tests,
which should always be the first methods to increase readability.

Traits

Traits are treated as classes.

Ternary Operator

Ternary operators are permissible when the entire ternary operation fits on one line.
Longer ternaries should be split into if else statements. Ternary operators should not ever be nested.
Optionally parentheses can be used around the condition check of the ternary for clarity:

Most IDEs even nowadays can't show start/end for keywords, with brackets it always works in pretty much every IDE, though.

If you intend to use the keywords in template files, you should at least be consistent and use them througout the files.
But in general it is better to also stick to curly brackets here for consistency throughout the codebase.

PHP Open Tags

Always use <?php or <?= instead of <?.

The <?= form should be used for echoing values of simple variables while the <?php form can be used for more complex code.

The short form is supported by the newest PHP versions as well and it makes your files less verbose, thus easier to read. It doesn't even require the semicolon (;) so feel free to omit it.

This <?= $x ?> way.

If you want to comment it out then you can do it easily:

This <?//= $x ?> way.

Commenting out with <!-- --> should be avoided as it is then visible in the resulting HTML output.

Comparison

Always try to be as strict as possible. If a non-strict test is deliberate it might be
wise to comment it as such to avoid confusing it for a mistake.

For testing if a variable is null, it is recommended to use a strict check:

Multi-line declaration/condition/concatenation

Multi-line control structures should have the parentheses in their own lines (similar to classes and methods):

if ( ($a==$b)&& ($b==$c)|| (Foo::CONST==$d)) {$a=$d;}

Careful with deep arrays

One mistake that often gets made:

$foo= [[0,1, 2], 3, 4];

This would effectively change all lines (and their indentation), if the array structure got normalized.
Arrays also need to minimize effects on the resulting diff, and as such indentation must always be the right one:

$foo= [[0,1, 2 ], 3, 4];

for example, max. normalized as:

$foo= [ [0,1,2 ],3,4];

As you can see, entries like 0 would not need any change on reorganizing, thus reducing overhead in work and making diffs easier to read as
they only show actual changes made.

Typehinting

Arguments that expect objects, arrays or callbacks (callable) can be typehinted. We only typehint public methods, though, as typehinting is not cost-free:

Avoid no-op methods

The first would allow no-ops like $this->foo() which does not do any operation at all.
So semantically this makes no sense. In this case no default value may be used and a first argument is actually required
for the first if statement to make sense ($this->foo($requiredArgument)). You can still pass null, of course, to break out early.
Default values may only be used if their usage does make this method still do an operation (apart from returning early).

Avoid private for class methods/properties

Most of the time private is used too eagerly, where protected would suffice.
Allow extending classes to extend the code. Don't assume it doesn't have to.
This is especially important for frameworks or vendor libraries that people would like to enhance or
customize in their applications.

In case you are acquainted with the "Open/Close Principle", it is in some cases OK to use
private to define clear public interfaces for classes.

Underscores for Private/Protected

It is not directly disallowed in PSR-2 to have the _ and __ visibility prefixes.
But it says one has a good reason to use them.
As most IDEs still don't really clearly display (in colors?) the difference between
public, protected and private, the following would be difficult to read:

Note that __ is also used for magic calls, and as such this recommendation is best used with the above hint of not using
private visibility in your code.
Otherwise please disregard and make sure you use an IDE that can display them properly. Using underscores with a lot of
private methods will probably be worse than sticking to the PSR-2 recommendation.

Return void vs null

@return void shall be used to document when a method is expected not to return anything, and when there is just a return; as "early return". Explicitly returning with return null; or return $this->foo(); shall be documented be as @return null etc.

HTML

All tags and attributes are lowercase.

CSS

Definition ideally as dashed name:

class: .some-class-name

id: #some-id-to-an-element

Both with lowercase characters (although classes are not case-sensitive, id's are!), the separator is minus [-].
You can use underscore [_] if it makes the separation of the identifier and the record id easier. E.g. my-id_33.
It will become necessary to do so if you use UUIDs (which contain minus chars).

Note: ids should be unique on the current page - so don't use them for iterating elements.
In general all styling should be class based. Ids are often abused for that.
But they usually serve the purpose of being identifiable via JS.
So they should ideally be mainly used for dynamic JS scripts.

Do not name the fields after their style, but after the function/meaning - as the style
can change and will result in things like .red { color: yellow;}.

JS

Ideally, JS related classes are prefixed with js- to separate them from the rest of the CSS and styling related class names:

<divclass="js-widget-toggle some-styling-class">...</div>

Further considerations

While so far the main focus was on the developer (readability), there are some additional optional guidelines that can help to further reduce diff size on code modification (maintainability).
Those can and should be automated, though, as there is no point in forcing the developer to take care of those manually.

The main idea is to keep each line independant from the others so removing or adding lines has minimal impact.

Multi-line arrays

Arrays that span across multiple lines can have a trailing comma to make sure that adding new rows does not change the previous row, as well.

$array= ['first','second', // Note the trailing comma];

Multi-line logic

For longer logic (method calls, operations) it can be helpful to put the trailing semicolon at the next line. Especially for fluid programming this will not show the previous row as modified.

$Object->doFirst()->doSecond();

This would also be consistent to the symmetric bracket placing in general.