php/e11ops.php

<html>
<h1>PHP Operators</h1>
<?php
require_once('env.php');
outBegin();
outH('strings');
outTB();
outTRH('expr', 'yield', 'gettype');
foreach (["substr('abcdef', 1, 2)", "substr('abcdef', -1)", "substr('', -1)"] as $e)
    outTRD($e, $v =eval("return $e;"), ($t = gettype($v)) . ($t === 'string' ? ": " . strlen($v) : ''));
outTBEnd();
out('attention && || have high priority, and or have low priority');
out('attention ?: is left associative and has priority between && > ?: > or');
$r=[['$v']
    , ['$v & 4 ? ($v & 2 ? a?? : b?:) : ($v & 1 ? c:? : d::)']
    , ['$v & 4 ? $v & 2 ? a?? : b?: : $v & 1 ? c:? : d::']
    , ['($v & 4 ? ($v & 2 ? a?? : b?:) : $v & 1) ? c:? : d::']];
for ($v=0; $v<=8; $v++) { 
    $r[0][] = $v;
    $r[1][] = $v & 4 ? ($v & 2 ? 'a??' : 'b?:') : ($v & 1 ? 'c:?' : 'd::');
    $r[2][] = $v & 4 ? $v & 2 ? 'a??' : 'b?:' : $v & 1 ? 'c:?' : 'd::';
    $r[3][] = ($v & 4 ? ($v & 2 ? 'a??' : 'b?:') : $v & 1) ? 'c:?' : 'd::' ;
}
outTb();
for ($i=0; $i<=3; $i++) {
    outTR();
    for ($k=0; $k<=9; $k++) {
        if ($i == 0 or $k == 0) 
            outTH($r[$i][$k]);
        else
            outTD($r[$i][$k]);
    }
}
outTbEnd();

out();
out('comparisons with/without type juggeling');
    outUL("1 <> 1 ==>", 1 <> 1);
    outLi("'a' == 'a '", 'a' == 'a ', ", 'a' === 'a '", 'a' === 'a ');
    outLi("'a' != 'a '", 'a' != 'a ', ", 'a' !== 'a  '", 'a' !== 'a ');
    outLi("6.0 == 6", 6.0 == 6, ", 6.0 === 6", 6.0 === 6);
    outLi("'7' == 7 '",'7' == 7, ", '7' === 7", '7' === 7);
    outLi("'7' != 7 '", '7' != 7, ", '7' !== 7" ,'7' !== 7);
    outLi("strcmp(a, b)", strcmp('a', 'b'));
    outLi("strcmp(12, 4)", strcmp(12, 4));
    outULEnd('comparisons end', 2);
out('increment undefined $abc ' . $abc . ' $abc++ ' . $abc++);
out('increment   defined $abc ' . ($abc = 5) . ' $abc++ ' . $abc++ . ' $abc=' . $abc . ' ++$abc=' . ++$abc);
out('return values and toNumber conversions');
    outUL('before call', 1);
    outLi('calling phpDemoRet(abc) = ' ,                phpDemoRet('abc'));
    outLi('calling 0 or phpDemoRet(1) =',          0 or phpDemoRet(1));
    outLi('calling 1 or phpDemoRet(1) =',          1 or phpDemoRet(1));
    outLi('calling 0 and phpDemoRet(1) =',         0 and phpDemoRet(1));
    outLi('calling 1 and phpDemoRet(1) =',         1 and phpDemoRet(1));
    outLi('calling 1 and phpDemoRet(void) =',      1 and phpDemoRet('void'));
    outULEnd('calling true + phpDemoRet(void) =', true + phpDemoRet('void'));
out('Strings');
outTB();
outTRH('code', 'expr', 'value');
    $errHnd = 0;
    $a = 'abcdefghi';
    ee('$a');
    ee('$a[0]');
    ee('$a[4]');
    ee('$a[4] = "E"; $a');
    ee('$a[4] = "QRS"; $a');
    ee('$a[4] = ""; $a');
    ee('method_exists(new ClassTS(), "__tostring")');
    ee('method_exists(new ClassEmpty(), "__tostring")');
    ee('method_exists(123.5e6, "__tostring")');
    for ($errHnd=1; $errHnd < 3; $errHnd++) {
        ee('throw new Error("throwing new Error"); $a');
        ee('trigger_error("triggering error"); $a');
        ee('(string) new Error("new***Error")');
        ee('(string) new MissingClass()');
        ee('(string) new ClassTS()');
        ee('(string) new ClassEmpty()');
        ee('(string) function () {}');
    }
    ee('#while (1) {out(strlen($a)); $a .= " *** $a"; }' . "\n;'out of memory not handled'");
    ee("''");
outTBEnd();
out('php error operator @, $php_errormsg is deprecated, use error_get_last()');
    outUL('phpError strPos() ' . (strPos()) . ", error_get_last() =", error_get_last()); 
    outLi('runtime directive track_errors is irrelevant = ' . ini_set('track_errors', 0));
    outLi('phpError @strPos(abc) ' . (@ strPos('abc')) . ", error_get_last() =", error_get_last()); 
    outLi("filetype(__file__)=" . filetype(__file__) . ", error_get_last() =", error_get_last());
    outLi("filetype(no no n1)=" . filetype('no no n1') . ", error_get_last() =", error_get_last());
    outLi("@filetype(no no n2)=" . @filetype('no no n2') . ", error_get_last() =", error_get_last());
    outULEnd("error_clear_last()=" . error_clear_last() . ", error_get_last() =",error_get_last());
out('phpOps end', 2);
outEnd(__file__);

class ClassEmpty {}
class ClassTS {
    function __tostring() {return 'ClassTS->__tostring'; }
}

function errHnd(int $errno , string $errstr , string $errfile , int $errline) {
    global $errHnd;
    out("errHnd " . ($errHnd===2 ? 'trigger' : 'throw') , " no=$errno, msg=$errstr, file=$errfile, line=$errline");
    if ($errHnd === 2)
        trigger_Error("errHnd=$errstr");
    else
        throw new Error("errHnd=$errstr");
    return true;
}
 
function ee($c) {
    global $a, $errHnd;
    if (false !== $x = strrpos($c, ';')) {
        outTRD(substr($c, 0, $x),  substr($c, $x+1), '');
        $c = substr($c, 0, $x+1) . ' return ' . substr($c, $x+1);
    } else {
        outTRD('', $c, '');
        $c = "return $c;";        
    }
    $e = '';
    if ($errHnd) { 
        $errOld = set_error_handler ('errHnd');
        out("set errHandler errHnd from", $errOld);
    }
    error_clear_last();
    try {
        $v=@eval("$c;");
    } catch (Throwable $t) {
        $e .= " catch=" . get_class($t) . '->'.  $t->getMessage();
    }
    if (null !== $l = error_get_last())
        $e .= " err=" . $l['message'];

    if ($errHnd) { 
        $errBa = set_error_handler ($errOld);
        out("set errHandler back from", $errBa, 'to', $errOld);
    }
    outW(($e === '') ? $v : substr($e, 1));
}

    function phpDemoRet($r) {
    outLi("in phpDemoRet($r)");
    if ($r !== 'void')
        return $r;
}

?>