Autor Zpráva
peta
Profil
Potreboval bych neco takoveho ve funkci __construct
    $this->func = !KONSTANTA ? $this->func1 : $this->func2;
Tohle mi ale pise Notice: Undefined property: classPokus::$func1 .

Kod je zhruba takovyto:
define("KONSTANTA",false);

class classPokus
{
public $func  = null;

    function __construct()
    {
    $this->func = !KONSTANTA ? $this->func1 : $this->func2;
    }

   public function func1()
    {
    return 111;
    }

   public function func2()
    {
    return 222;
    }

$pokus = classPokus;
$pokus->func();
Bertram
Profil
peta:
Ahoj,
takto se přistupuje k veřejné vlastnosti objektu:
$object->publicProperty;
a takto k veřejné metodě objektu:
$object->publicMethod();

Tvůj kód by mohl vypadat takto,
<?php
define("KONSTANTA",FALSE);

class Pokus {

    public $vlastnost;

    public function __construct($parametr) {
        $this->vlastnost = $parametr;
    }

    public function metoda() {
        if ($this->vlastnost) {
            return 111;
        }
        return 222;
    }
}

$pokus = new Pokus(KONSTANTA);
echo $pokus->metoda();
ale vůbec nechápu, k čemu může sloužit, prozradíš?
Joker
Profil
peta:
Potreboval bych neco takoveho ve funkci __construct
>
$this->func = !KONSTANTA ? $this->func1 : $this->func2;
Je nějaký důvod nepoužít úplně triviální řešení?

class classPokus
{
  function func()
  {
    return KONSTANTA ? $this->func1() : $this->func2();
  }
}
peta
Profil
Ja tu funkci nechci volat. Ucel neni tajny, jen jsem to chtel zjednodusit pro dotaz.

function query1($query)
{
return mysql_query($query);
}

function query2($query)
{
echo $query;
$result = mysql_query($query) or die(mysql_error());
return $result;
}

$query = !$debug ? query1 : query2;
$query("SELECT * FROM tabulka");
$query("SELECT * FROM tabulka");
$query("SELECT * FROM tabulka");
...

V podstate jde o to, ze uz pri construct priradim do query spravnou funkci a pozdeji se nemusis ifem ptat (viz Joker, tak to mam ted take), zda je zapnuty debug mod. Kdyz v tom Jokerove priklade zavolas tu funkci 100x, tak tam mas navic 100x if navic, ktery by tam byt nemusel.
Alphard
Profil
Jako název volané metody lze použít proměnnou, ale nejsem si jist, jestli je to tady úplně vhodné.
Jan Tvrdík
Profil
peta:
$query1 = function ($query) {
    return mysql_query($query);
};

$query2 = function ($query) {
    echo $query;
    $result = mysql_query($query) or die(mysql_error());
    return $result;
};

$query = !$debug ? $query1 : $query2;
$query("SELECT * FROM tabulka");
$query("SELECT * FROM tabulka");
$query("SELECT * FROM tabulka");
peta
Profil
Tak, ted mi to pise undefined method.
Call to undefined method classSql::query() in C:\wamp\www\riv-fyzika\pp-pokus\setc\sql_inc.php on line 29

<?php
class classSql
{
public $conn  = null;
public $db    = null;
public $query = null;
private $query1 = null;
private $query2 = null;

    function __construct()
    {
    $this->connect();
    //$this->query = !SQL_DEBUGMODE ? $this->query1 : $this->query2;
    if (SQL_DEBUGMODE)
        {
        echo "<style>.highlight {border-bottom:1px solid #FFE6DD;padding-bottom:3px;margin-bottom:3px;}</style>";
        }
    $this->query1 = function ($query)
        {
        return mysql_query($query,$this->conn);
        };
    $this->query2 = function ($query)
        {
        echo "\n<div class=\"highlight\">query = ".$query."</div>";
        $result = mysql_query($query,$this->conn) or die('Chyba mysql_query. ' . mysql_error($this->conn));
        return $result;
        };
    $this->query = !SQL_DEBUGMODE ? $this->query1 : $this->query2;
    $this->query("SET NAMES utf8"); // radek 29
    }
}
Joker
Profil
peta:
Kdyz v tom Jokerove priklade zavolas tu funkci 100x, tak tam mas navic 100x if navic, ktery by tam byt nemusel.
Takže na těch 100 volání bude rozdíl v rychlosti skriptu přibližně… nula?
Na straně záporů je duplikování kódu, horší srozumitelnost a údržba.

Já osobně bych pro situaci v [#4] volil jednu funkci.
Výsledkem „optimalizací“ tohohle druhu je podle mě horší a nakonec paradoxně i pomalejší kód. Pomalejší proto, že čas investovaný do přemýšlení nad vynecháním jednoho IFu šlo investovat do optimalizací s řádově větším efektem.
A někdy (když „optimalizátor“ něco nedomyslí) se i stane, že ten „optimalizovaný“ kód je sám o sobě pomalejší než ten původní. Čehož si „optimalizátor“ nevšimne, protože jako výsledek optimalizace mu stačí subjektivní pocit, že kód urychlil. Ono objektivní měření většinou stejně ani není možné, protože třeba u kódu v [#4] efekt té optimalizace ani podle mě změřit nepůjde, náhodné rozdíly mezi měřeními budou větší.
peta
Profil
Tak, mam reseni. Sice trochu na pikacu, ale funguje.
<?php
class classSql
{
public $conn  = null;
public $db    = null;
public $query_func = null;
public $query = null;

    public function query($query)
    {
    return call_user_func($this->query_func,$query,$this->conn);
    }

    function __construct()
    {
    $this->connect();
    $query1 = function ($query,$conn)
        {
        return mysql_query($query,$conn);
        };
    $query2 = function ($query,$conn)
        {
        echo("\n<div class=\"highlight\">query = ".$query."</div>");
        $result = mysql_query($query,$conn) or die('Chyba mysql_query. ' . mysql_error($conn));
        return $result;
        };
    $this->query_func = !SQL_DEBUGMODE ? $query1 : $query2;
    if (SQL_DEBUGMODE)
        {
        echo("<style>.highlight {border-bottom:1px solid #FFE6DD;padding-bottom:3px;margin-bottom:3px;}</style>");
        }
    $this->query("SET NAMES utf8");
    }
?>
Hm, ten parser nejak nezvlada apostrofy. Jednou jsou spravne, treba u SET NAMES, ale podruhe, u echo, to parsuje snad jako html kod?
Joker
Profil
peta:
Tak, mam reseni.
Cituji sám sebe:
A někdy (když ‚optimalizátor‘ něco nedomyslí) se i stane, že ten ‚optimalizovaný‘ kód je sám o sobě pomalejší než ten původní.
Testovací kód (Pozn. z nějakého důvodu na testovacím webu nejde $x = function, takže jsem použil create_user_func a vytváření objektů vynechal z měření):
<?php
define("SQL_DEBUGMODE", true);

function getmicrotime($t){
  list($usec, $sec) = explode(" ",$t);
  return ((float)$usec + (float)$sec);
}

class classSql
{
public $conn  = null;
public $db    = null;
public $query_func = null;
public $query = null;
 
    public function query($query)
    {
    return call_user_func($this->query_func,$query,$this->conn);
    }
 
    function __construct()
    {
    $query1 = create_function('$query,$conn', "return true;");
    $query2 = create_function('$query,$conn', "return false;");
    $this->query_func = !SQL_DEBUGMODE ? $query1 : $query2;
    }
}

class ClassSqlJoker
{
public $conn  = null;
public $db    = null;
public $query_func = null;
public $query = null;
 
    public function query($query)
    {
      if(!SQL_DEBUGMODE) return true;
      else return false;
    }
    
    function __construct()
    {
    }
}

$test = new ClassSqlJoker();
$tStart = microtime();
for($i=0; $i<10000; $i++)
{
  $test->query(true);
}
$tEnd = microtime();
echo("<p>if: ".(getmicrotime($tEnd) - getmicrotime($tStart))."s</p>");

$test = new classSql();
$tStart = microtime();
for($i=0; $i<10000; $i++)
{
  $test->query(true);
}
$tEnd = microtime();
echo("<p>call_user_func: ".(getmicrotime($tEnd) - getmicrotime($tStart))."s</p>");

?>
Výsledky (průměr 5 měření):
Jedna funkce s větvením (if): 0,010s
Dvě funkce s call_user_func: 0,031s

Čili po X hodinách snahy urychlit konstrukci, jejíž dopad na rychlost skriptu v reálu není měřitelný (protože v praxi tam bude to mysql_query s řádově delším časem) máme „optimalizaci“, která je 3x pomalejší než původní kód.
Tož asi tak.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: