[PHP] Tablica obiektów jako zmienna sesji

Witam wszystkich,

mam mały problem. Otóż stworzyłem sobie klasę Point. Następnie utowrzyłem tablice obiektów. Problem się zaczyna gdy chce ją przekazać w sesji do następnej strony. Tablica teoretycznie przechodzi - jej długość się zgadza. Niestety próba odwołania się do jej obiektów kończy się nie powodzeniem. Gdzie robię błąd? Poniżej zamieszczam kody do obu stron.

<?php

    class Point{

        private $id;

        private $x;

        private $y;


        function __construct(){

            $this->x = 0;

            $this->y = 0;

        }

        /*function __construct($war1, $war2){

            $this->x = $war1;

            $this->y = $war2;

        }*/

        public function setID($id){

            $this->id = $id;

        }

        public function setX($wsp){

            $this->x = $wsp;

        }

        public function setY($wsp){

            $this->y = $wsp;

        }

        public function getID(){

            return $this->id;

        }

        public function getX(){

            return $this->x;

        }

        public function getY(){

            return $this->y;

        }

        public function showAll(){

            echo $this->x." ".$this->y."
";

        }

    }

?>

<?php

include 'classPoint.php';

function losujBezPowtorzen($ilosc, $sizeWidth, $sizeHeight){

    $wsp = array();

    echo $sizeWidth." ".$sizeHeight."
";

    //ustawienie współrzędnych x - mogą się powtarzać


    $count = 0;

    while($count<$ilosc) {

        $wsp[$count] = new Point();

        $x = rand(0, $sizeWidth);

        $y = rand(0, $sizeHeight);

        $booltmp = TRUE;

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

            if($wsp[$i]->getX() == $x && $wsp[$i]->getY() == $y){

                $booltmp = FALSE;

                break;

            }

         }

         if ($booltmp==TRUE) {

             $wsp[$count]->setID($count+1);

             $wsp[$count]->setX($x);

             $wsp[$count]->setY($y);

             $count++;

         }

    }

    return $wsp;

}

?>

<?php        

$point = array();

        //losowanie współrzędnych

        $point = losujBezPowtorzen($ilosc, $resolution[0], $resolution[1]);


        //wyświetlanie współrzędnych

        for($i = 0; $i < $ilosc; $i++){

            echo $i.": ".$point[$i]->getX().", ".$point[$i]->getY()."
";

        }

        $_SESSION['point'] = $point;

        $_SESSION['xy'] = $resolution;

        header('Location: ./rysuj.php');

        ?>

<?php

    session_start();

    include 'classPoint.php';

    $array = $_SESSION['points'];

    echo count($array); //długość wyświetlanej tablicy - OK

    echo $array[0]->getX(); //błąd - włącza się __autoload

?>

No ja żadnej klasy nie widzę :stuck_out_tongue:

Z takich skrawków to tylko wróżka może coś powiedzieć.

Daj print_r albo var_dump dla tablicy i dla zmiennej sesyjnej, będziesz widział co zawierają.

Używasz innej nazwy odczytując sesję (point vs points).

btw. ja też tu żadnej klasy nie widzę…

trochę dziwne - mam wartości NULL…

trochę dziwne - mam wartości NULL…

No masz wartości null bo czytasz w sesji z elementu którego nie ma :stuck_out_tongue:

jak mogę czytać z elementu którego nie ma. Funkcja losująca zwraca mi tablicę obiektów. Poźniej jest ona wyświetlana i wszystko działa - dodałem kody których brakowało. Niestety po wysłaniu ich w sesji mam nula.

Dodane 18.02.2012 (So) 17:16

zmieniłem tą literówkę. Mam za to na ekranie coś takiego:

array(30) { [0]=> object(__PHP_Incomplete_Class)#1 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(1) ["x":"Point":private]=> int(941) ["y":"Point":private]=> int(296) } [1]=> object(__PHP_Incomplete_Class)#2 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(2) ["x":"Point":private]=> int(162) ["y":"Point":private]=> int(199) } [2]=> object(__PHP_Incomplete_Class)#3 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(3) ["x":"Point":private]=> int(602) ["y":"Point":private]=> int(891) } [3]=> object(__PHP_Incomplete_Class)#4 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(4) ["x":"Point":private]=> int(1470) ["y":"Point":private]=> int(360) } [4]=> object(__PHP_Incomplete_Class)#5 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(5) ["x":"Point":private]=> int(1160) ["y":"Point":private]=> int(757) } [5]=> object(__PHP_Incomplete_Class)#6 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(6) ["x":"Point":private]=> int(1547) ["y":"Point":private]=> int(434) } [6]=> object(__PHP_Incomplete_Class)#7 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(7) ["x":"Point":private]=> int(437) ["y":"Point":private]=> int(465) } [7]=> object(__PHP_Incomplete_Class)#8 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(8) ["x":"Point":private]=> int(224) ["y":"Point":private]=> int(648) } [8]=> object(__PHP_Incomplete_Class)#9 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(9) ["x":"Point":private]=> int(313) ["y":"Point":private]=> int(897) } [9]=> object(__PHP_Incomplete_Class)#10 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(10) ["x":"Point":private]=> int(1523) ["y":"Point":private]=> int(562) } [10]=> object(__PHP_Incomplete_Class)#11 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(11) ["x":"Point":private]=> int(1582) ["y":"Point":private]=> int(420) } [11]=> object(__PHP_Incomplete_Class)#12 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(12) ["x":"Point":private]=> int(1389) ["y":"Point":private]=> int(152) } [12]=> object(__PHP_Incomplete_Class)#13 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(13) ["x":"Point":private]=> int(1472) ["y":"Point":private]=> int(708) } [13]=> object(__PHP_Incomplete_Class)#14 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(14) ["x":"Point":private]=> int(1115) ["y":"Point":private]=> int(1030) } [14]=> object(__PHP_Incomplete_Class)#15 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(15) ["x":"Point":private]=> int(616) ["y":"Point":private]=> int(115) } [15]=> object(__PHP_Incomplete_Class)#16 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(16) ["x":"Point":private]=> int(1558) ["y":"Point":private]=> int(604) } [16]=> object(__PHP_Incomplete_Class)#17 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(17) ["x":"Point":private]=> int(188) ["y":"Point":private]=> int(228) } [17]=> object(__PHP_Incomplete_Class)#18 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(18) ["x":"Point":private]=> int(1320) ["y":"Point":private]=> int(889) } [18]=> object(__PHP_Incomplete_Class)#19 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(19) ["x":"Point":private]=> int(1021) ["y":"Point":private]=> int(285) } [19]=> object(__PHP_Incomplete_Class)#20 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(20) ["x":"Point":private]=> int(1028) ["y":"Point":private]=> int(597) } [20]=> object(__PHP_Incomplete_Class)#21 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(21) ["x":"Point":private]=> int(571) ["y":"Point":private]=> int(913) } [21]=> object(__PHP_Incomplete_Class)#22 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(22) ["x":"Point":private]=> int(1595) ["y":"Point":private]=> int(640) } [22]=> object(__PHP_Incomplete_Class)#23 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(23) ["x":"Point":private]=> int(1208) ["y":"Point":private]=> int(263) } [23]=> object(__PHP_Incomplete_Class)#24 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(24) ["x":"Point":private]=> int(290) ["y":"Point":private]=> int(67) } [24]=> object(__PHP_Incomplete_Class)#25 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(25) ["x":"Point":private]=> int(486) ["y":"Point":private]=> int(830) } [25]=> object(__PHP_Incomplete_Class)#26 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(26) ["x":"Point":private]=> int(1063) ["y":"Point":private]=> int(1009) } [26]=> object(__PHP_Incomplete_Class)#27 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(27) ["x":"Point":private]=> int(414) ["y":"Point":private]=> int(603) } [27]=> object(__PHP_Incomplete_Class)#28 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(28) ["x":"Point":private]=> int(927) ["y":"Point":private]=> int(713) } [28]=> object(__PHP_Incomplete_Class)#29 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(29) ["x":"Point":private]=> int(1328) ["y":"Point":private]=> int(485) } [29]=> object(__PHP_Incomplete_Class)#30 (4) { ["__PHP_Incomplete_Class_Name"]=> string(5) "Point" ["id":"Point":private]=> int(30) ["x":"Point":private]=> int(787) ["y":"Point":private]=> int(795) } } 

Fatal error: main() [function.main]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Point" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in E:\x86\Zend\Apache2\htdocs\rysuj.php[/code]

Tak powinno zadziałać już, jeżeli nie ma innych błędów:

<?php

    require_once 'classPoint.php';

    session_start();

    $array = $_SESSION['points'];

    echo count($array); //długość wyświetlanej tablicy - OK

    echo $array[0]->getX(); //błąd - włącza się __autoload

?>

Wydaje mi się, że źle dołączasz definicję klasy.

Klasę trzeba ładować PRZED zastartowaniem sesji i nie przy pomocy include, tylko require (lub require_once) - poczytaj sobie o tym bo jest tu różnica dość istotna.

djpizmak - dzięki wielkie za pomoc. Powiem szczerze, że długo bym jeszcze szukał a w życiu bym nie wpadł na pomysł z require_once. Mam zatem ostatnie pytanie w kwestii tego tematu. W przedostatnim podanym kodzie w I poście na samym dole znajduje się header(…) do przekierowania. Lokalnie na serwerze apacha wszystko działa. Problem się zaczyna się gdy umieszcze całą stronkę na serwerze - wówczas nie dochodzi do przekierowania. Wiesz może dlaczego? PRzecież żadne dane nie są wysyłane do przeglądarki.

Odnośnie klasy i sesji, to obiekt przed zapisaniem do zmiennej sesyjnej przepuść przez funkcje serialize()

…przy odczycie ze zmiennej sesyjnej zaś przepuść przez unserialize() - pozbędziesz się błędów.

Co do header’a, to skorzystaj z buforowania - ob_start(); na początku pliku i ob_end_flush(); na jego końcu.

a nie jest czasem tak -podejrze od wersji 4, mogę się mylić - że wszystkie dane przesyłane za pomocą sesji - są serializowane z automatu?

Dodane 18.02.2012 (So) 17:59

czy ob_start i ob_end_flush dawać w każdym pliku php czy tylko tam gdzie są header’y?

Do przekierowania z header nie dochodzi, ponieważ użyłeś funkcji echo przed header’em - a tego robić nie wolno! :slight_smile:

Jeżeli chcesz wyświetlać jakiś tekst to skorzystaj z tego co Ci napisał adpawl - użyj: ob_start(); oraz ob_end_flush();

Serializować obiektów nie trzeba. Przy przesyłaniu sesji serializacja i tak następuje.

Chyba że chcesz przesłać sobie taką tablicę przez $_COOKIES to wtedy już musisz serializować sobie sam - ręcznie.

Dodane 18.02.2012 (So) 18:12

Jeżeli się nie mylę, bo dawno już nie piszę w php :slight_smile: to chodzi tu o to, aby skorzystać z tej funkcji tak:

ob_start();

// wszelkiego typu wypisywania przy uzyciu echo

ob_end_flush();

header(‘Location: ./cos.php’);

Ta funkcja zbiera wszystkie dane od miejsca ob_start i jak napotka ob_end_flush to wypisuje je, a potem wykonuje header’a.

erializing objects - objects in sessions

session_register

Buforowanie tylko tam gdzie jest header, w innych plikach nie ma potrzeby jego stosowania

_edit

headera wstaw w bufor - między OBy :wink:

Jeżeli się nie mylę, bo dawno już nie piszę w php :slight_smile: to chodzi tu o to, aby skorzystać z tej funkcji tak:

ob_start();

// wszelkiego typu wypisywania przy uzyciu echo

ob_end_flush();

header(‘Location: ./cos.php’);

albo tak:

ob_start();

// wszelkiego typu wypisywania przy uzyciu echo

header(‘Location: ./cos.php’);

ob_end_flush();

Nie pamiętam na 100% :slight_smile:

Ta funkcja zbiera wszystkie dane od miejsca ob_start i jak napotka ob_end_flush to wypisuje je, a potem wykonuje header’a.

Jeżeli nie masz na stronie funkcji header to nie ma potrzeby korzystać z tych ob_start i ob_end_flush.

Mam jeszcze mała prośbę. Otóż w trakcie prowadzenia z Wami koledzy dyskusji zmieniłem trochę kod. Wygląda on następująco

<?php

    if(isset($_COOKIE['resolution'])){

        if(isset($_GET['ilosc']) && isset($_GET['zasieg'])){

            if(is_numeric($_GET['ilosc']) && is_numeric($_GET['zasieg'])){

                if(($_GET['ilosc'] > 0) && ($_GET['zasieg'] >0)){

                    session_start();

                }else{

                    header('Location: ./generator.php?error=1'); //podane dane nie sią typu numerycznego

                }

            }else{

                header('Location: ./generator.php?error=2'); //podane dane nie sią typu numerycznego

            }

        }else{

            header('Location: ./generator.php?error=3'); //podane dane nie sią typu numerycznego

        }

    }else{

        if(isset($_GET['szerokosc']) && isset($_GET['wysokosc'])){

            if(is_numeric($_GET['szerokosc']) && is_numeric($_GET['wysokosc'])){

                if(isset($_GET['ilosc']) && isset($_GET['zasieg'])){

                    if(is_numeric($_GET['ilosc']) || is_numeric($_GET['zasieg'])){

                        if(($_GET['szerokosc'] >= 10) && ($_GET['wysokosc'] >= 10) && ($_GET['ilosc'] > 0) && ($_GET['zasieg'] > 0)){

                            session_start();

                            require_once 'classPoint.php';

                            require_once 'losujBezPowtorzen.php';


                            $resolution = '';

                            if(isset($_COOKIE['resolution'])){

                                $resolution = $_COOKIE['resolution'];

                            }else{

                                $resolution = $_GET['szerokosc']."x".$_GET['wysokosc'];

                            }

                            $resolution = explode("x", $resolution);

                            unset ($_GET['szerokosc'], $_GET['wysokosc']);


                            $ilosc = $_GET['ilosc']; //ilosc urzadzen do wygenerowania

                            $zasieg = $_GET['zasieg']; //zasieg urzadzen generowanych

                            unset ($_GET['ilosc'], $_GET['zasieg']);


                            $point = array();

                            //losowanie współrzędnych

                            $point = losujBezPowtorzen($ilosc, $resolution[0], $resolution[1]);


                            //wyświetlanie współrzędnych

                            $_SESSION['graf'] = $point;

                            $_SESSION['xy'] = $resolution;

                            header('Location: ./rysuj.php');

                        }else{

                            header('Location: ./generator.php?error=8'); //podane dane nie sią typu numerycznego

                        }

                    }else{

                        header('Location: ./generator.php?error=7'); //podane dane nie sią typu numerycznego

                    }

                }else{

                    header('Location: ./generator.php?error=6'); //podane dane nie sią typu numerycznego

                }

            }else{

                header('Location: ./generator.php?error=5'); //podane dane nie sią typu numerycznego

            }

        }else{

            header('Location: ./generator.php?error=4'); //podane dane nie sią typu numerycznego

        }

    }

?>

Niestety do przekierowania nadal nie dochodzi. W częsci głównej oczywiście. Osobiście nie lubie php, programuje w Javie. PHP jest z pewnych względów odgórnych teraz wykonywane

@djpizmak, raczej albo tak

Ma być wewnątrz bufora a nie poza nim. Jak dasz poza, to wyjdzie na to samo co bez buforowania.

@braciszek, całość w bufor …a ciastko serializuj/derserializuj skoro chcesz przekazać tablicę

_edit

ob_start na samym początku skryptu, ob_end_flush na samym końcu

A jak mam kilka tych headerów tak jak na poprzedniej stronie - ostatni post - to gdzie ob_start wstawić?

Nie możesz tak robić że sobie dwa razt sesje otwierasz i jeszcze nigdzie jej nie zamykasz.

Jak już Ci mówiłem require_once() wykonujesz PO session_start a tak NIE WOLNO :stuck_out_tongue:

Najpierw musisz dołączyć definicje klas przy pomocy require_once a potem dopiero startować sesję - bo sesja przy odpalaniu dokonuje niejawnej deserializacji - a jak to ma zrobić skoro nie zna jeszcze definicji Twojej klasy (bo dołączasz ją już po wystartowaniu sesji)?

Wszystkie require dajesz na samym początku skryptu.

A dodatkowo:

Dodane 18.02.2012 (So) 18:44

Aaaaaffffffffeeeeeeeeeeeeee Java :slight_smile:

Nienawidzę tego języka okrutnie (a może nawet nie samego języka a maszyny wirtualnej java czy serwerów aplikacji, jboss czy glasfish to takie same zamulacze :stuck_out_tongue: ) - przez całe studia musiałem się z nim męczyć. Java potrafi tylko mulić i nic więcej :stuck_out_tongue:

Jak to mówi mój wykładowca - “Java to jest zabaweczka, kredeczki i sobie malujemy… Programy należy pisać w języku C” :lol:

owszem, w c/c++ nigdy nie umiałem wyjść po za konsolę. W javie jest to śmiesznie proste. W php z kolei nie ogarniam w ogóle. Wolałbym się skupić na asp.net albo czymś innym niż php

A czemu nie możesz tego skryptu napisać w asp.net? Masz tam mvc i bardzo miło się pisze, a C# bardzo podobny do javy :slight_smile: