# Znajomosc PHP

## Belliash

Witam wszystkich,

Od pewnego czasu pisze sobie rozne rzeczy w PHP, sek w tym ze nie zawsze sobie radze.

Wiem ze to forum nie jest do tego przeznaczone, ale czy moglby tu od czasu-do-czasu (oczywiscie w 1 watku)?

Czy moglbym liczyc na Wasza pomoc w nauce tego jezyka?

----------

## 13Homer

 *Belliash wrote:*   

> Czy moglbym liczyc na Wasza pomoc w nauce tego jezyka?

 

Nie oczekujesz chyba, że ktoś w ciemno zadeklaruje pomoc? Jak będziesz miał z czymś kłopot, to podrzuć temat, pewnie ktoś pomoże. Było już C++, shell itp. to i na PHP znajdzie się rada :)

----------

## Redhot

 *Belliash wrote:*   

> Czy moglbym liczyc na Wasza pomoc w nauce tego jezyka?

 

No problem  :Wink: 

----------

## Belliash

No to pierwszy problem jaki napotkalem....

Chcialbym zrobic obsluge bledow... w tym celu robie funkcje handeError($level, $code, $message); ktora ma na celu sprawdzenie czy jest to blad, ostrzezenie czy zwykle powiadomienie i odpowiednie wyswietlenie wiadomosci oraz kodu.

Chcialbym jednak by mialo to postac, np:

E_ERROR: From function $FUNKCJA called from $PLIK, line $LINIA: $WIADOMOSC (Code number $KOD)

A wiec potrzebne mi sa nazwa pliku oraz linia...

I jesli zrobie funkcje np

```
getLine() {

return __LINE__;

}
```

to ona wyswietli mi linie w ktorej znajduje sie ta funkcja a nie z ktorej lini ta funkcja zostala wywolana... To samo tyczy sie nazwy pliku (__FILE__).

Z 2 strony mozna by zastosowac taki kod:

function getBacktrace(){ return array_pop(debug_backtrace()); }

```
function ab(){

    echo print_r(getBacktrace(),true);

}
```

Ale ona zwroci mi cos w stylu:

```
Array

(

   [file] => index.php

   [line] => 10

   [function] => ab

   [args] => Array

       (

       ))
```

z tym ze plik to bedzie plik ktory zostal wywolany, a jesli funkcja jest w jakim pliku ktorego index.php wywolal poprzez require_once? Lub nawet jest w jakiejs klasie?

Jedyne dzialajace cudo jakie przychodzi mi do glowy to handeError($level, $code, $message, $file = null, $line = null);

i jako parametry podawac __FILE__ oraz __LINE__ aczkolwiek szukam jakich alternatyw by moc zrobic to w bardziej porzadny i elegancki sposob...

Najlepiej aby w ogole nie trzeba bylo podawac linii i pliku, tylko by funckja sama zwracala plik i linie z ktorej zostala wywolana...

Z gory dziekuje za sugestie  :Smile: 

Arfrever: Dodano znaczniki kodu.

----------

## 13Homer

Zacznijmy od tego, której wersji PHP używasz, bo wedle tego handler może dostawać numer linii.

----------

## Belliash

ja mam PHP5 aczkolwiek ccialbym jak najwieksza kompatybilnosc wstecz zachowac.

Napisalem takze posta na neowin.net i 1 opsoba odpisala mi:

"The backtrace is what you are looking for. If the element at the 'top' of the array returned is not the information you're looking for, it will likely be the next element below it."

Chciaz nie bardzo kumam o co chodzi o jak mialbym te informacje wyciagnac...

To sie raczej tyczylo tego:

```
function getBacktrace(){ return array_pop(debug_backtrace()); }

function ab(){

echo print_r(getBacktrace(),true);

}
```

Z tym, ze zwroci mi index.php linia 22 np bo tam zostala zainicjowana klasa, a mnie interesuje konkretny plik i linia z ktorej to zostala wywolala na funkcja...

Arfrever: Dodano znaczniki kodu.

----------

## 13Homer

 *Belliash wrote:*   

> ja mam PHP5 aczkolwiek ccialbym jak najwieksza kompatybilnosc wstecz zachowac.

 

Aż do której wersji? debug_backtrace pojawił się w wersji 4.3.0. set_error_handler jest, jak widać, od wersji 4.0.1 i w dokumentacji nie widzę nic o tym, żeby w handlerze zmieniała się liczba argumentów. Jak chcesz się bawić w ręczne pobieranie linii to proponuję skorzystanie z funkcjonalności zmiennej liczby argumentów - jak do handlera nie dostaniesz numeru linii albo nazwy pliku, to wyciągniesz to jakoś ręcznie.

 *Quote:*   

> Chciaz nie bardzo kumam o co chodzi o jak mialbym te informacje wyciagnac...
> 
> To sie raczej tyczylo tego:
> 
> function getBacktrace(){ return array_pop(debug_backtrace()); }

 

Skoro debug_backtrace zwraca tablicę, to pobierasz drugi jej element: $bt = debug_backtrace(); array_pop($bt); return array_pop($bt). Jest to po to, że uparłeś się napisać specjalną funkcję, która grzebie po bt, więc to ona jest na samym szczycie bt.

EDIT::

```
<?

require_once('x2.php');

set_error_handler('xx');

function xx($errno, $errstr, $errfile, $errline, $errcontext) {

echo '<pre>';

print_r(debug_backtrace());//$errcontext);

echo '</pre>';

die("errno: $errno, errstr: $errstr, errfile: $errfile, errline: $errline");

}

$q = new q();

$q->qq();

zz();

?>
```

```
<?

require_once('x3.php');

function zz() {

echo $a11;

}

?>
```

```
<?

class q {

function qq() {

echo $qwe;

}

}

?>
```

I dostaję:

```
Array

(

    [0] => Array

        (

            [file] => /mnt/large/home/homer/emes/zlecenia/x3.php

            [line] => 4

            [function] => xx

            [args] => Array

                (

                    [0] => 8

                    [1] => Undefined variable: qwe

                    [2] => /mnt/large/home/homer/emes/zlecenia/x3.php

                    [3] => 4

                    [4] => Array

                        (

                        )

                )

        )

    [1] => Array

        (

            [file] => /mnt/large/home/homer/emes/zlecenia/x.php

            [line] => 13

            [function] => qq

            [class] => q

            [object] => q Object

                (

                )

            [type] => ->

            [args] => Array

                (

                )

        )

)

errno: 8, errstr: Undefined variable: qwe, errfile: /mnt/large/home/homer/emes/zlecenia/x3.php, errline: 4
```

czyli jak najbardziej to, czego oczekiwałem, gdyz na samym szczycie bt jest dokładne położenie błędnej linii.

Zapodaj swój kod, bo najwyraźniej coś pokręciłeś.

----------

## Belliash

hmm....

no dobra z tym se juz jakos poradze...

pytanie nastepne dotyczy programowania objektowego...

Mam taki kod:

```
class VDB {

    /* Gets a reference to the only instance of database class */

    function &getDatabase() {

        static $database;

        if(!isset($database)) {

            require_once(base . 'config.php');

            $dbconf = new VConfiguration;

            switch(strtolower($dbconf->DBTYPE)) {

                case 'pgsql':

                    require_once(base . 'includes/db/pgsql.php');

                    $dbtype = "PgSQL";

                    break;

                case 'sqlite':

                    require_once(base . 'includes/db/sqlite.php');

                    $dbtype = "SQLite";

                    break;

                default:

                    require_once(base . 'includes/db/mysql.php');

                    $dbtype = "MySQL";

                    break;

            }

            $class = 'VDatabase' . $dbtype;

            $database =& new $class();

            unset($class);

            unset($dbconf);

            unset($dbtype);

        }

        return $database;

    }

    /* Gets a reference to the only instance of database class and connects to DB */

    function &getDatabaseConnection() {

        static $instance;

        if(!isset($instance)) {

            require_once(base . 'config.php');

            $dbconf = new VConfiguration;

            switch(strtolower($dbconf->DBTYPE)) {

                case 'pgsql':

                    require_once(base . 'includes/db/pgsql.php');

                    $dbtype = "PgSQL";

                    break;

                case 'sqlite':

                    require_once(base . 'includes/db/sqlite.php');

                    $dbtype = "SQLite";

                    break;

                default:

                    require_once(base . 'includes/db/mysql.php');

                    $dbtype = "MySQL";

                    break;

            }

            $class = 'VDatabase' . $dbtype;

            $instance =& new $class();

            $instance->connect($dbconf->DBHOST, $dbconf->DBUSER, $dbconf->DBPASS, $dbconf->DBNAME, $dbconf->PREFIX, false);

            if(!$instance->db_connect_id) {

                die('Could not connect to the database!');

            }

            unset($class);

            unset($dbconf);

            unset($dbtype);

        }

        return $instance;

    }

} /* class */

class VConfig {

    var $config = array();

    var $ready = false;

    /* Checks if we have already obtained configuration from database */

    function checkReady() {

        return $this->ready;

    }

    /* Returns a proper config value */

    function getConfigItem($item) {

        if($this->ready === true) {

            return $this->config[$item];

        }

    }

    /* Gets a reference to the only instance of VConfig class */

    function &getInstance() {

        $instance =& new VConfig();

        return $instance;

    }

    /* Gets configuration from database */

    function obtainConfig() {

        if(!($config = $this->getConfigItem('config'))) {

            $db =& VDB::getDatabase();

            $query = 'SELECT * FROM ' . $db->prefix('config');

            if(!($result = $db->query($query))) {

                VErrors::displayError(V_ERROR, 'Cannot obtain configuration from database!', 100);

            }

            $this->config = array();

            while($row = $db->fetchRow($result)) {

                $this->config[$row['config_name']] = $row['config_value'];

            }

            $this->ready = true;

            return true;

        }

        $this->ready = false;

        return false;

    }

    /* Resets configuration */

    function resetConfig() {

        if($this->ready === true) {

            unset($this->config);

            $this->config = array();

            $this->ready = false;

            return true;

        }

        return false;

    }

    /* Sets a config item */

    function setConfigItem($item, $value) {

        if($this->ready === true) {

            $this->config[$item] = $value;

        }

    }

} /* class */

$xdb =& VDB::getDatabaseConnection();   // tu nastepuje polaczenie z baza danych

$config = new VConfig;

$config->obtainConfig();    // ta linia psuje :P
```

Odkomentowanie psujacej linii powoduje taki oto blad:

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource, in file: includes/db/mysql.php, line: 215

Error 100 - Cannot obtain configuration from database!!

Klasa VDatabaseMySQL rozszerza klase VDatabase.

jest tam zmienna $db_connect_id (w VDatabase) ktorej wartosc jest nadawana przez funkcje VDatabaseMySQL::connect.

Zalozmy ze wynosi ona 5;

Nastepnie mamy:

$config = new VConfig;

$config->obtainConfig();

i w funkcji VConfig::obtainConfig() mamy:

$db =& VDB::getDatabase();

Sek w tym ze wszystkie wartosci klasy (np nasz $this->db_connect_id) sa tutaj wyzerowane...

Nie zgadza sie wiec db_connect_id i dostaje w/w warninga...

Co moge / powinienem zrobic, aby te wartosci nie byly zerowane?

Nie jestem zainteresowany uzywaniem: "global $xdb;" wewnatrz funkcji VConfig::obtainConfig();

Z gory dzieki za pomoc w tym zapewne banalnym problemiku...

Widac gdzies czegos niedoczytalem do konca.

Mam nadzieje ze mnie nakierujecie  :Wink: 

----------

## 13Homer

"$instance = new $class();"?

----------

## Belliash

 *13Homer wrote:*   

> "$instance = new $class();"?

 

to to samo jak bym napisal

$instance = new VDatabaseMySQL();

pprostu nie wiemy jaka klase uzyc... bo mam ich kilka VDatabaseMySQL, VDatabasePgSQL, ...

wszystkie maja extends VDatabase...

a wiec mamy

$class = VDatabaseMySQL;

$instance =& new $class();

----------

## 13Homer

 *Belliash wrote:*   

>  *13Homer wrote:*   "$instance = new $class();"? 
> 
> $instance =& new $class();

 

Spróbuj bez ampersandu.

----------

## Belliash

 *13Homer wrote:*   

>  *Belliash wrote:*    *13Homer wrote:*   "$instance = new $class();"? 
> 
> $instance =& new $class(); 
> 
> Spróbuj bez ampersandu.

 

nic nie zmienia...

Juz dziala... Zmiany jakie poczynilem w kodzie:

http://arcon.svn.sourceforge.net/viewvc/arcon?view=rev&revision=1620

EDITED:

Czemu po ustawieniu set_error_handler nie ma roznicy gdy wykonam "funkcja" lub "@funkcja" ? Za kazdym razem sypie bledami...

Natomiast gdy wylacze wlasnego 'handlera' bledow wszystko wraca do normy...

Ktos wie o co chodzi?

----------

## 13Homer

A w dokumentacji jest tak:

 *Quote:*   

> It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator.

 

----------

## Belliash

 *13Homer wrote:*   

> A w dokumentacji jest tak:
> 
>  *Quote:*   It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator. 

 

przyznaje moja wina...

niedopatzrenie...

Ale dzieku za zwrocenie uwagi....

if(error_reporting() = 0) { return } powinno zalatwic sprawe  :Wink:  Taka mam przynajmneij nadzieje  :Razz: 

----------

## Belliash

```
Run-time notify: Non-static method VSystem::getDatabase() should not be called statically in /var/www/localhost/htdocs/vimba/index.php on line 26

Run-time notify: Non-static method VSystem::getHandler() should not be called statically in /var/www/localhost/htdocs/vimba/index.php on line 29
```

 *index.php wrote:*   

> /* Connect to the database */
> 
> VSystem::getDatabase(true);
> 
> /* Create the application */
> ...

 

```
    /* Gets a reference to the only instance of database class and connects to DB */

    function &getDatabase($connect = false) {

        static $instance;

        if(!isset($instance)) {

            require_once(base . 'config.php');

            $dbconf = new VConfiguration;

            switch(strtolower($dbconf->DBTYPE)) {

                case 'firebird':

                    require_once(base . 'includes/db/firebird.php');

                    $dbtype = "Firebird";

                    break;

                case 'msaccess':

                    require_once(base . 'includes/db/msaccess.php');

                    $dbtype = "MsAccess";

                    break;

                case 'mssql':

                    require_once(base . 'includes/db/mssql.php');

                    $dbtype = "MsSQL";

                    break;

                case 'mysqli':

                    require_once(base . 'includes/db/mysqli.php');

                    $dbtype = "MySQLi";

                    break;

                case 'odbc':

                    require_once(base . 'includes/db/odbc.php');

                    $dbtype = "ODBC";

                    break;

                case 'oracle':

                    require_once(base . 'includes/db/oracle.php');

                    $dbtype = "Oracle";

                    break;

                case 'pgsql':

                    require_once(base . 'includes/db/pgsql.php');

                    $dbtype = "PgSQL";

                    break;

                case 'sqlite':

                    require_once(base . 'includes/db/sqlite.php');

                    $dbtype = "SQLite";

                    break;

                default:

                    require_once(base . 'includes/db/mysql.php');

                    $dbtype = "MySQL";

                    break;

            }

            $class = 'VDatabase' . $dbtype;

            $instance = new $class;

            if($connect === true) {

                $instance->connect($dbconf->DBHOST, $dbconf->DBUSER, $dbconf->DBPASS, $dbconf->DBNAME, $dbconf->PREFIX, false);

                if(!$instance->db_connect_id) {

                    VErrors::raiseError('Could not connect to the database!', 1001);

                }

            }

            unset($class);

            unset($dbconf);

            unset($dbtype);

        }

        return $instance;

    }

    /* Gets a reference to the only instance of selected class */

    function &getHandler($name) {

        static $instance = array();

        $name = strtolower(trim($name));

        $class = 'V' . ucfirst($name);

        if(!isset($instance[$class])) {

            $instance[$class] = new $class();

        }

        return $instance[$class];

    }
```

Ktos jest w stanie wyjasnic mi skad te ostrzezenia (E_STRICT wprowadzone w PHP5) i jak sie tego za przeproszeniem badziewia pozbyc?  :Smile: 

----------

## 13Homer

Do cytowania plików używaj code="plik", a nie quote="plik".

"VSystem::getDatabase(true);" to wywołanie metody statycznej z klasy VSystem, ale getDatabase nie jest statyczna. Albo zmienisz jej prototyp (nie pamiętam jak się definiuje motody statyczne) albo musisz utworzyć obiekt klasy VSystem: $vs = new VSystem(); $vs->getDatabase(true);

----------

## manwe_

Metody statyczne wymagają przed "function" słowa .... .... ... "static"  :Wink:  Mała uwaga, spowoduje to syntax error w PHP4 [gdybyś gdzieś takiego używał z tym kodem].

----------

## Belliash

noo wlasnie to musi dzialac z PHP4, a wiem ze inne CMSy tez tak wywoluja funkcje a przed nimi slowa kluczowego 'static' nie ma...

Powiadomienia tego tez nie ma, bo to sie chyba run-time notify zwie (blad 2048)?  :Smile: 

Moze poprostu zignorowac to i zakazac wyswietlania tych komunikatow?  :Neutral: 

----------

## manwe_

Jeżeli musi być PHP4 i 5, to zostaje:

1. niewyświetlanie ostrzeżen,

2. includowanie dwóch różnych wersji kodu w zależności od wersji,

3. eval i np. str_replace('static function', 'function', $text) jeżeli PHP4. 

p.s.

PHP4 to przeszłość, jest systematycznie zabijany, pomyśl nad wymuszeniem upgrade'u  :Smile: 

----------

## 13Homer

 *manwe_ wrote:*   

> Jeżeli musi być PHP4 i 5, to zostaje:
> 
> 1. niewyświetlanie ostrzeżen,
> 
> 2. includowanie dwóch różnych wersji kodu w zależności od wersji,
> ...

 

Mogę jeszcze dodać stworzenie funkcji globalnych, które będą obsługiwały singletony (np. klasy VSystem) - robiłem taki numer w C++, gdy potrzebowałem funkcji, które musiały korzystać z muteksów (pierwsza wersja ich nie miała, więc były to zwykłe funkcje zagnieżdżone w namespace). Kod "z zewnątrz" się w ogóle nie zmienił.

Jak chce się mieć kompatybilność wsteczną, to trzeba cierpieć.

I jeszcze jedno: po kiego grzyba jest coś takiego jak getDatabase()? Na ogół takie coś się opakowuje klasą, która ma zwrócić jakieś dane, np listę użytkowników. Później się okaże, że dane trzeba pobierać z pliku, a nie bazy i trzeba pół aplikacji przerabiać.

----------

## Belliash

Sa 2 funkcje: getHandler i getDatabase.

1 z nich zwraca wskaznik do zadanej klasy (singleton).

2 zas, o ktora pytasz, robi dokladnie to samo, ale tylko i wylacznie dla klasy z obsluga DB, przy czym jesli nadamy zmiennej $connect wartosc true to od razu laczy z baza danych.

A wiec 1 wywolanie tej funkcji ma postac VSystem::getDatabase(true); co powoduje polaczenie z baza danych. Kolejne wywolania zas maja postac VSystem::getDatabase() co ma takie samo dzialanie jak getHandler.

W sumie moglbym wymusic migracje do PHP5  :Razz: 

Jak by nie patrzec wchodzi po malu PHP6  :Wink: 

Hmm....

```
Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 115

Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 116

Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 115

Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 116

Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 115

Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 116
```

A co powiecie na takie cudo?

----------

## 13Homer

 *Belliash wrote:*   

> Sa 2 funkcje: getHandler i getDatabase.
> 
> 1 z nich zwraca wskaznik do zadanej klasy (singleton).
> 
> 2 zas, o ktora pytasz, robi dokladnie to samo, ale tylko i wylacznie dla klasy z obsluga DB, przy czym jesli nadamy zmiennej $connect wartosc true to od razu laczy z baza danych.
> ...

 

To akurat widać z kodu i przykładów użycia. Chodziło mi o to, żeby z VSystem zrobić singletona.

Zdajesz sobie sprawę z tego, że konstrukcja getDatabase(true) jest chora? Zawsze musisz wiedzieć, że należy ją wykonać na samym początku, przed innymi. Singletony są po to, żeby o takich rzeczach nie wiedzieć - tworzy się obiekt i od razu inicjuje, reszta aplikacji nie wie, czy dostała świeży wskaźnik, czy już "używany", bo jak to pierwsze, to trzeba jeszcze zainicjować.

A jeśli aplikacja nie będzie potrzebowała połączenia z bazą, to po co je tworzyć?

 *Quote:*   

> W sumie moglbym wymusic migracje do PHP5 :P
> 
> Jak by nie patrzec wchodzi po malu PHP6 ;)

 

Wchodzi już Oracle 11, a niektóre banki twardo trzymają się 9.2. A masz jakieś lepsze argumenty niż "bo niektóre konstrukcje nie działają jak trzeba w 4 i sypie ostrzeżeniami".

 *Quote:*   

> 
> 
> ```
> Notice: Resource ID#19 used as offset, casting to integer (19) in includes/db/mysql.php on line 115
> 
> ...

 

Wygląda na kod w stylu (nazwy funkcji z sufitu):

$q = mysql_exec();

$x = $y[$q];

Komuś się coś nie udało.

----------

## Belliash

to CMS... Wszystkie ustawienia ma zapisane w bazie danych...

Robie co prawda obsluge rozszerzen (dodatkow, addonow... jak zwla ak zwal), ale tam i tak jak ktos bedzie potrzebowal dostep do DB to zrobi tylko $db =& VSystem::getDatabase();

Ew. fukcje getDatabase moglbym zapisac tak:

```
    /* Gets a reference to the only instance of database class and connects to DB */

    static function &getDatabase() {

        static $instance;

        if(!isset($instance)) {

            require_once(base . 'config.php');

            $dbconf = new VConfiguration;

            switch(strtolower($dbconf->DBTYPE)) {

                case 'firebird':

                    require_once(base . 'includes/db/firebird.php');

                    $dbtype = "Firebird";

                    break;

                case 'msaccess':

                    require_once(base . 'includes/db/msaccess.php');

                    $dbtype = "MsAccess";

                    break;

                case 'mssql':

                    require_once(base . 'includes/db/mssql.php');

                    $dbtype = "MsSQL";

                    break;

                case 'mysqli':

                    require_once(base . 'includes/db/mysqli.php');

                    $dbtype = "MySQLi";

                    break;

                case 'odbc':

                    require_once(base . 'includes/db/odbc.php');

                    $dbtype = "ODBC";

                    break;

                case 'oracle':

                    require_once(base . 'includes/db/oracle.php');

                    $dbtype = "Oracle";

                    break;

                case 'pgsql':

                    require_once(base . 'includes/db/pgsql.php');

                    $dbtype = "PgSQL";

                    break;

                case 'sqlite':

                    require_once(base . 'includes/db/sqlite.php');

                    $dbtype = "SQLite";

                    break;

                default:

                    require_once(base . 'includes/db/mysql.php');

                    $dbtype = "MySQL";

                    break;

            }

            $class = 'VDatabase' . $dbtype;

            $instance = new $class;

            $instance->connect($dbconf->DBHOST, $dbconf->DBUSER, $dbconf->DBPASS, $dbconf->DBNAME, $dbconf->PREFIX, false);

            if(!$instance->db_connect_id) {

                VErrors::raiseError('Could not connect to the database!', 1001);

            }

            unset($class);

            unset($dbconf);

            unset($dbtype);

        }

        return $instance;

    }
```

A po co laczy sie z baza? Bo piszesz ze moze ktos tego nie chciec...

Ale ten CMS odczytuje z DB np tytul strony, styl i inne ustawienia...

Co do tych powiadomien. Wystepuja w takiej funkcji:

```
    /* Returns a numerical array that corresponds to the fetched row and moves the internal data pointer ahead */

    function fetchRow($query_id = 0) {

        if(!$query_id) {

            $query_id = $this->query_result;

        }

        if($query_id) {

            $this->row[$query_id] = mysql_fetch_array($query_id, MYSQL_ASSOC);

            return $this->row[$query_id];

        } else {

            return false;

        }

    }
```

To mozna by naprawic tak:

```
    /* Returns a numerical array that corresponds to the fetched row and moves the internal data pointer ahead */

    function fetchRow($query_id = 0) {

        if(!$query_id) {

            $query_id = $this->query_result;

        }

        if($query_id) {

            $this->row[(int) $query_id] = mysql_fetch_array($query_id, MYSQL_ASSOC);

            return $this->row[(int) $query_id];

        } else {

            return false;

        }

    }
```

Tylko to chyba nie zbyt poprawnie?  :Neutral: 

----------

## 13Homer

 *Belliash wrote:*   

> to CMS...
> 
> [...]
> 
> A po co laczy sie z baza? Bo piszesz ze moze ktos tego nie chciec...
> ...

 

No to musiało mi umknąć, że to CMS. W takim razie sprawa jasna i nie ma sensu zmieniać.

 *Quote:*   

> $this->row[$query_id] = mysql_fetch_array($query_id, MYSQL_ASSOC);

 

$query_id jest typu resource, zaś tablice można indeksować tylko napisami albo liczbami (więc PHP dokonuje konwersji niejawnej - wymuszanie przez rzutowanie usuwa tylko ostrzeżenie, a nie istotę problemu). To jest błędna konstrukcja, bo resource pełni rolę czegoś w rodzaju uchwytu do nieznanej struktury i używanie tego do czego innego jest ryzykowne (może się np. coś pozmieniać w którejś wersji PHP). Przez analogię z C: traktowanie wskaźnika do struktury jako liczby i dokonywanie na niej jakichś obliczeń jest w zasadzie możliwe, ale co najmniej dziwaczne.

----------

## Belliash

a jakby  to skonwertowac na stringa? powinno zawierac wtedy dokladnie taka sama zawartosc ... tylko typ by sie zmienil...

chociaz w sumie to sie chyba nawet nie da w ten sposob...

----------

## 13Homer

 *Belliash wrote:*   

> a jakby  to skonwertowac na stringa? powinno zawierac wtedy dokladnie taka sama zawartosc ... tylko typ by sie zmienil...

 

A jak chcesz skonwertować resource na stringa? Może myślisz o rzutowaniu, a nie konwersji? Zmienne typu resource są z zasady niekonwertowalne i jeśli będziesz to robił, to na własne ryzyko.

Co jest złego w zwróceniu od razu całej tablicy?

----------

## Belliash

Pominmy to na razie...

Chwilowo zastanawiam sie czy daloby sie ten fragment kodu jakos ladniej zapisac. Moze krocej? Bardziej profesonalnie? Zalecacie jakies zmiany?

Szczegolnie dumam nad przedostatnia linijka  :Neutral: 

```
$ret = 'http';

if(!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) != 'off') {

    $ret .=  's';

}

$ret .=  '://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];

$tmp = explode('/', $ret);

$ret = substr($ret, 0, (strlen($ret) - strlen($tmp[count(explode('/', $ret)) - 1])));

echo $ret;
```

Dzieki za uwagi!

----------

## 13Homer

strrpos?

----------

## Belliash

hmm....

widac nie poszukalem dobrze odpowiedniej funkcji...

W sumie to teraz:

```
$tmp = explode('/', $ret);

$ret = substr($ret, 0, (strlen($ret) - strlen($tmp[count(explode('/', $ret)) - 1]))); 
```

mozna zastapic:

```
$ret = substr($ret, 0, (strrpos($ret, '/') + 1));
```

Dziekuje slicznie  :Smile: 

BTW: Co sadzicie o pisaniu kodu tak, by pozniej nie bylo problemow z PHP6 ? Czy moze lepiej sobie teraz to darowac, a pozniej, gdy PHP6 sie przyjmie dokonywac poprawek kodu?

Swoja droga, da sie uruchomic jednoczesnie 2 kopie Apache na 1 systemie? Np na porcie 80 z PHP5 i na porcie 81 z PHP6?  :Razz: 

----------

## unK

Skoro niektóre serwery maja do wyboru php4 i php5, to na pewno się da.

----------

## SlashBeast

Zamiast dwa aache to jeden, i php po fastcgi, .php, .php5 => "127.0.0.1:4444" i .php4 => "127.0.0.1:4445" dla przykładu,

----------

## Belliash

hmmm....

Aktalnie mam apache na porcie 81 z PHP5, chcialbym do tego doinstalowac PHP6 (mam nadzieje ze inny slot  :Razz: ) i jak potem skonfigurowac Apache, by na porcie 82 bylo PHP6?  :Smile:  Polecicie jakas lektore? Bo na gentoo-wiki zdaje sie tego nie byc? Choc przyznam ze szukalem pobieżnie... Nie chce sie wykrecac i zwalac na inne wydarzenia, ale jestem w trajcie sesji  :Razz:  I aktualnie programuje/ucze sie PHP na zmiane z nauka matematyki (analiza wymiata ;/)...

I jeszce 1 pytanie:

Majac takie 2 stringi:

$text = '<fdffd>fdfd</fdfd>{Block|left,right}<fdfd></fdfd>';

$key = '{Block|*}';

Jak byscie szukali $key w $text, przy czym '*' to wszystko do '|' do pierwszego napotkanego '}'?

Bo w tym konkretnym przypadku chcialbym w innej zmiennej zapiasc "{Block|left,right}", a wiec calosc.

Arfrever: Ortografia

----------

## 13Homer

A czego dotyczy problem? Nie słyszałeś o wyrażeniach regularnych, czy nie potrafisz takiego wyrażenia zbudować?

----------

## Belliash

 *13Homer wrote:*   

> A czego dotyczy problem? Nie słyszałeś o wyrażeniach regularnych, czy nie potrafisz takiego wyrażenia zbudować?

 

Wlasnie tego zeby znalazl {COKOLWIEK|*} w innych stringu, przyczym gwiazdke zastapil czymkolwiek (tak jak w Uniksie lub DOSie, ale do pierwszego wystapienia } i zapisal to w innej zamiennej tak ze $a = {COLKOLWIEK|TU_TEZ_COS_JEST}

Pewnie preg_match? regex?

Tylko jak by to mialo w caloscie (taka dzialajaca wersja) wygladac?  :Neutral: 

```
$text = "<dfdsfsd></fdfd>fdfsdfsdf<fdfsd>fgdsfsd</fdsfsd>{Block|left,right}<fdfsdfsd>fdfsdds</fdssdfs>{fdfdf}<fdsfsd>gfgd</fsdfsdsd>";

$key = '{Block|*}';

if(substr($key, '|')) {

    $find = '{Block\|(.*)}';

    ereg($find, $text, $match);

    echo $match[0];

}
```

pokazuje mi:

{Block|left,right}fdfsdds{fdfdf}

zamiast:

{Block|left,right}

I glowie sie co tu zmienic...

Teraz czytam ze eregi nei ma w PHP6... Robimy wiec preg_match:  :Wink: 

$text = "<dfdsfsd></fdfd>fdfsdfsdf<fdfsd>fgdsfsd</fdsfsd>{Block|left,right|}<fdfsdfsd>fdfsdds</fdssdfs>{fdfdf}{Block|top|}<fdsfsd>gfgd</fsdfsdsd>";

$key = '{Block|*}';

if($find = substr($key, 0, strrpos($key, '|'))) {

    $find .= '\|(.*?)\|}';

    preg_match($find, $text, $match);

    echo $match[0];

    echo $match[1];

}

Ale:

1) Ucina mi  { }

2) $match powinien byc tablica z 2 pozycjami (i jest). Tylko 1 pozycja powinna zawierac: {Block|left,right|} a 2: {Block|top|} a wygladaja tak: 1 -> Block|left,right|  2 -> left,right 

 :Neutral: 

----------

## 13Homer

Prawdę mówiąc nie wiem, czy jest sens wyjaśniać Ci takie rzeczy. O wyrażeniach regularnych na sieci jest pełno i bez problemu można rozwiązanie podstawowych problemów. Tak: podstawowych, popełniasz elementarne błędy. W skrócie: * działa tak, że zawsze stara się dopasować możliwie najdłuższy ciąg znaków (operator zachłanny czy jakoś tak), zaś {} mają w wyrażeniach regularnych specjalne znaczenie (nie wiem, czy akurat w tym przypadku ma to znaczenie).

Poczytaj najpierw o tych wyrażeniach. Wyrażenia regularne mają niewiele wspólnego z tym, co jest zaimplementowane w bashu.

PS. [^}]*

----------

## Belliash

 *13Homer wrote:*   

> Prawdę mówiąc nie wiem, czy jest sens wyjaśniać Ci takie rzeczy. O wyrażeniach regularnych na sieci jest pełno i bez problemu można rozwiązanie podstawowych problemów. Tak: podstawowych, popełniasz elementarne błędy. W skrócie: * działa tak, że zawsze stara się dopasować możliwie najdłuższy ciąg znaków (operator zachłanny czy jakoś tak), zaś {} mają w wyrażeniach regularnych specjalne znaczenie (nie wiem, czy akurat w tym przypadku ma to znaczenie).
> 
> Poczytaj najpierw o tych wyrażeniach. Wyrażenia regularne mają niewiele wspólnego z tym, co jest zaimplementowane w bashu.
> 
> PS. [^}]*

 

A tak nie moze byc?  :Razz: 

Troche nad tym czasu spedzilem, i w sumie chcialbym juz tylko abys w miare mozliwosci oraz wolnego czasu przejrzal ten kod i ew. skarcil mnie za ew naduzycia czy brzydkie hacki  :Wink: 

```
                if($find = substr($key, 0, strpos($key, '|'))) {

                    $find = str_replace('{', '/\{'. $find);

                    $find .= '\|(.*?)\|\}/';

                    preg_match_all($find, $this->theme[$type], $match);

                    $functions = array_keys(array_flip($match[0]));

                    for($i = 0; $i < count($functions); $i++) {

                        $this->theme[$type] = str_replace($functions[$i], '{any_funcion_with_params_goes_here}', $this->theme[$type]);

                    }

                }
```

A tak w ogole, to chce Ci bardzo podziekowac za wszystko co do tej pory dla mnie zrobiles  :Mr. Green: 

----------

## 13Homer

```
$text = "<dfdsfsd></fdfd>fdfsdfsdf<fdfsd>fgdsfsd</fdsfsd>{Block|left,right|}<fdfsdfsd>fdfsdds</fdssdfs>{fdfdf}{Block|top|}<fdsfsd>gfgd</fsdfsdsd>";

$key = '/{Block\|[^}]*}/';

preg_match_all($key, $text, $match);

echo '<pre>';

print_r($match);

echo '</pre>';
```

O to chodziło?

----------

## Belliash

No na jedno wychodzi  :Razz: 

----------

## Belliash

```
var $options = array();

    /* Processes and substitutes tags with other code */

    function compileTemplate() {

        if(!empty($this->theme['error'])) {

            $type = 'error';

        } else if(!empty($this->theme['body'])) {

            $type = 'body';

        } else {

            return false;

        }

        if(count($this->constants) > 0) {

            $tags = array_keys($this->constants);

            foreach($tags as $key) {

                if($find = substr($key, 0, strpos($key, '|'))) {

                    $find = str_replace('{', '/\{', $find);

                    $find .= '\|(.*?)\|\}/';

                    preg_match_all($find, $this->theme[$type], $match);

                    $functions = array_keys(array_flip($match[0]));

                    for($i = 0; $i < count($functions); $i++) {

                        $options = substr($functions[$i], (strpos($functions[$i], '|') + 1), (strrpos($functions[$i], '|') - 7));

                        $options = str_replace(' ', '', $options);

                        $this->options = explode(',', $options);

                        $this->theme[$type] = str_replace($functions[$i], $this->constants[$key], $this->theme[$type]);

                    }

                } else {

                    $this->theme[$type] = str_replace($key, $this->constants[$key], $this->theme[$type]);

                }

            }

        }

        return true;

    }

    /* Initialises style management */

    function initialise() {

        VThemes::addConstant('{Block|*|}', VExtensions::displayBlock($this->options[0]));

        VThemes::addConstant('{Content}', VExtensions::loadContent());

        VThemes::addConstant('{Validator}', VThemes::validator());

    }

    /* Loads template from file and saves in variable */

    function loadTemplate($file = 'style') {

        switch($file) {

            case 'error':

                if($this->theme['error'] = file_get_contents(BASE_PATH . 'styles/' . $this->style . '/' . $file . '.tpl')) {

                    return true;

                }

                break;

            case 'module':

                if($this->options[$this->style]['module']) {

                    if($this->theme['module'] = file_get_contents(BASE_PATH . 'styles/' . $this->style . '/' . $file . '.tpl')) {

                        return true;

                    }

                }

                break;

            case 'offline':

            case 'style':

                if($this->options[$this->style]['healthy']) {

                    if($this->theme['body'] = file_get_contents(BASE_PATH . 'styles/' . $this->style . '/' . $file . '.tpl')) {

                        return true;

                    }

                }

                break;

        }

        return false;

    }

    function raiseElement() {

        echo $this->theme['body'];

    }
```

Wykonuja sie kolejno:

loadTemplate();

initialise();

compileTemplate();

raiseElement();

A wiec kolejno:

1) laduje styl z plik i zapisuje w zmiennej.

2) Dodaje elementy do tablicy ktore bedzie zamienial.

3) Kompiluje styl (zamienia elementy)

4) Wyswietla styl.

Pod czas wykonywania punkty 3. Wszystkie parametry zapisuje w $this->options (chodzi mi o bloki), a potem wykonuje funkcje zamiany, ktora korzysta z $this->options[0], gdzie zapisany jest parametr z informacje ktory blok wyswietlic. Chwilowo funkcja wyswietlajaca blok wyglada tak:

```
    function displayBlock($block) {

        return 'Block ' . $block . ' goes here<br />';

    }
```

I wyswietla jedynie "Block  goes here". Nie wyswietla $block. Idzmy dalej $this->options[0] jest puste. Idzmy jeszcze dalej $this->options nie jest zmienna tablicowa (pusta zmienna). Natomiast gdy w funkcji compileTemplate() dopiszemy linijke echo $this->options[0] to wyswietla na samej gorze "left". A wiec ja ustawia...

Nie rozumiem jednak zcemu nie jest to dostepne dalej...   :Question: 

----------

