Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 15 of 15
  1. #1
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Question object type session variables?

    can objects be passed across pages as session variables?
    like, i have an object class called mcq. its properties are question, a, b, c, d, e, ans. kind of like so:
    class mcq{
    ...
    $this->question = "What color is the sky?";
    $this->a = "Red";
    $this->b = "Blue";
    $this->c = "Green";
    $this ->ans="b";
    ....
    }
    and it has a method that returns whether the user's answer is correct or not, by comparing the user's answer with $this->ans. this method is called "correctAns".

    on mcq1.php, the user answers some MCQs, each question is actually a member of the mcq object array. so that mcq[0] is the first question object (with a,b,c, the correct answer,etc), and mcq[1] is the second object with all its properties, and so on.

    on submitting, the user is directed to mcq2.php, where his/her results are displayed. I want to pass the mcq objects' array as a session variable from mcq1.php to mcq2.php, so that on mcq2.php page i can check each object's own answer with the user's answers submitted in the previous form.
    using a loop to get the mcq objects works without any errors.
    PHP Code:
    for($i 0$i $no_mcqs$i++){
    eval(
    "\$mcq[".$i."]  =  \$_SESSION['mcq[".$i."]'];");

    but when i try to print out, say, $mcq[0]->ans, i don't get anything.
    and if i want to check the user's first answer using :
    $result = $mcq[0]->correctAns($user_answer[0]);
    i get this error:
    Fatal error: Call to a member function on a non-object in c:\phpdev\www\learning\mcq2.php on line 69

    apparently, $mcq[0] did get passed on as a session variable but hasn't maintained its integrity as an object.

    is it that session variables can't be objects?
    Last edited by ASAAKI; 04-03-2003 at 03:21 PM.
    'If you don't stand for something, you'll fall for anything.'

  • #2
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    On your second page, before you instantiate the session in which you previously stored the object, you have to include the class definition for this class. If you stored it in a separate file like Quiz.class.php, it's a matter of adding a require_once before the call to session_start() is issued.
    Otherwise the object can not be deserialized correctly and you end up with this error message.

    Session variables can hold objects, and this is a major advantage for building object-oriented persistance layers in PHP webapps.

  • #3
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    not working.
    i can't require 'mcqclass.php' before session_start(); because then it says 'headers already sent'. so i required it after session_start.

    i get the same error as i said before. and if i attempt to :
    PHP Code:
    echo($mcq[0]->id); 
    then i also get this:
    Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in c:\phpdev\www\learning\mcqclass.php on line 57

    but i use the mcq object without any problems, making new instances of it and using its methods, on the first page.
    'If you don't stand for something, you'll fall for anything.'

  • #4
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Look into your class file and see if somewhere output is echoed/printed to the browser. This is the cause of your "headers already sent" error. Your class file should only consist of valid php code within the <?php tags, watch for an eventual newline before or after these tags.

    What I describes is the correct way to use objects in sessions and is also described in the manual. You can't just include the class file after starting the session, that will never work.

    Your last error description seems to be caused by the previous errors, but it's hard to say without knowing the exact source code.

  • #5
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    i don't exactly understand.
    here's my source, 'mcqclass.php':
    PHP Code:
    <?php
    class MCQ{
    var 
    $id;
    var 
    $type;
    var 
    $mark;
    var 
    $question;
    var 
    $a;
    var 
    $b;
    var 
    $c;
    var 
    $d;
    var 
    $e;
    var 
    $ans;

    function 
    MCQ($id){
    $this->id $id;
    $sql="SELECT `a`,`b`,`c`,`d`,`e`,`ans`,`type`,`mark`, `question` FROM `mcq` WHERE `id`='".$this->id."'";
    $result=mysql_query($sql) or die("Sorry, unable to extract MCQ question.");
    $row_array=mysql_fetch_row($result);
    $this->$row_array[0];
    $this->$row_array[1];
    $this->$row_array[2];
    $this->$row_array[3];
    $this->$row_array[4];
    $this->ans $row_array[5];
    $this->type $row_array[6];
    $this->mark $row_array[7];
    $this->question $row_array[8];
    }

    function 
    printQ($qno){
    echo(
    "[<span class='no'>".$qno."</span>] ".$this->question." </span><br>");
    }


    function 
    printChoices($qno){
    echo(
    "A <input type='radio' value='a' name='m".$qno."' class='rdo'> &nbsp &nbsp &nbsp ".$this->a."<br>");
    echo(
    "B <input type='radio' value='b' name='m".$qno."' class='rdo'> &nbsp &nbsp &nbsp ".$this->b."<br>");
    echo(
    "C <input type='radio' value='c' name='m".$qno."' class='rdo'> &nbsp &nbsp &nbsp ".$this->c."<br>");
    echo(
    "D <input type='radio' value='d' name='m".$qno."' class='rdo'> &nbsp &nbsp &nbsp ".$this->d."<br>");
    if(
    $this->e){echo("E <input type='radio' class='rdo' value='e' name='m".$qno."'> &nbsp &nbsp &nbsp ".$this->e."<br><br>");}
    }

    /*
    function saveProgress($userid,$s_ans){
    if($s_ans){//if user has given any answer for this question then
    // select from the db to check if he's already saved progress on this question before.
    // if he has, we'll use an update query.
    // if he hasn't we'll insert.
    }
    }
    */

    function correctAns($s_ans){
    $s_ans==$this->ans $this->result $this->result 0;
    }
    ?>
    i don't have any extra lines around the php tags...

    this is the first time i'm doing OOP so i'm likely to be making some major mistakes...
    Last edited by ASAAKI; 04-04-2003 at 02:44 PM.
    'If you don't stand for something, you'll fall for anything.'

  • #6
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Code:
    function correctAns($s_ans){
    $s_ans==$this->ans ? $this->result = 1 : $this->result = 0;
    }
    } // <- this bracket is missing, your class is not "closed"
    ?>
    There was the above error in your code excerpt and it lead to the last error you described. Try storing the object again with the fixed code and report if the other errors persist.

  • #7
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    thanks. silly mistake

    now all the errors have gone, except the "call to a member function on a non-object".
    there is no error any more when i do:
    echo($mcq[0]->id);
    in fact there is nothing when i do that. i still don't get that mcq object's id.

    but when i use a method of the object, like:
    $result[$i]=$mcq[$i]->correctAns($s_ans[$i]);

    then i get the above "non-object" error.
    'If you don't stand for something, you'll fall for anything.'

  • #8
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    How do you save your array of objects in the session? If you do it like

    PHP Code:
    session_start();
    $_SESSION['mcq'] = $mcq
    and retrieve it on the second page like

    PHP Code:
    // class definition... see above
    session_start();
    $mcq $_SESSION['mcq'];
    echo 
    $mcq[0]->question
    then the stored question attribute should be printed out. Observe that your correctAns() method is not returning anything, so nothing useful could be stored in the $result array.

    In your first post, you do some strange scripting with eval() which purpose is not clear to me. If you can provide some more info how you a) store the object array and b) retrieve the object array from the session we should be able to narrow down the source of the error.

  • #9
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    i added "return $result;" in the correctAns function, and i used the code you said. for some reason, it still isn't working.

    Here's an explanation of the eval code, etc.

    the site i'm working on has lessons, and exercises after each lesson.

    depending on the lesson, there may be any number of MCQs. The 'mcq' table in the db has a field called 'lesson_id'. after the user decides to take the exercise of the lesson he's currently studying, the lesson_id that he chooses gets passed on to the exercises page, and is used as a parameter to extract all the IDs of the MCQs, 'WHERE mcq.lesson_id='.$lesson_id.
    using that query i get all the IDs of the relevant MCQs that should be displayed. according to the number of rows fetched, i make the variable '$no_mcqs'.
    then, according to the IDs i fetched, i use a loop to instantiate new MCQ objects, and pass these IDs one by one into the MCQ function to create a new MCQ object of the mcq[] array:

    PHP Code:
    for($i=0;$i<$no_mcqs$i++){
    $j=$i+1// this is just to get the printed question number to start from 1 instead of 0.
    // the next two lines fetch the mcq IDs and then the id[] array gets these IDs
    $row_array=mysql_fetch_array($result); 
    $id[$i]=$row_array[0]; 
    // now create new MCQ objects, using the ID we just extracted.
    // each object is part of the mcq[] array.
    $mcq[$i]=new MCQ($id[$i]);
    // print out the question and the choices of the current object, using the MCQ methods.
    $mcq[$i]->printQ($j); 
    $mcq[$i]->printChoices($i); 

    then, at the bottom of the form i have a hidden input element that stores the number of MCQs in this exercise.
    after answering the questions, the user hits 'Done' and the form gets submitted.
    almost forgot, i do this to store the object array:
    PHP Code:
    if(!session_is_registered($mcq)){
    session_register($mcq);
    $_SESSION['mcq']=$mcq;

    actually, before i used a verbose loop to do that, a lot like what's mentioned below as the old code that i'm not using now.

    hope everything's clear so far. this was all on mcq1.php.

    on the next page, mcq2.php, i do this:
    PHP Code:
    require("mcqclass.php");
    session_start();
    $no_mcqs=$_GET['no_mcqs'];
    // the connection stuff....

    /* now i'm using a loop (for the number of MCQs that there are),
     to assign all the mcq objects in the SESSION's mcq array to the 
    mcq[] array on this page. 
    let's suppose the current value of $i in this loop is 1. so the eval 
    code will evaluate to:
           $mcq[1] = $_SESSION['mcq[1]']; 
    this way all the objects in the SESSION's array should get into the mcq array of this page.
    */

    for($i 0$i $no_mcqs$i++){
    eval(
    "\$mcq[".$i."] = \$_SESSION['mcq[".$i."]'];");

    that's what i was doing, but now, as you said, i simply get the array like this rather than looping through every single member of the array:
    PHP Code:
    $mcq=$_SESSION['mcq']; 
    then i try to:
    PHP Code:
    echo($mcq[0]->id); 
    which apparently does nothing.

    and when i try to:
    PHP Code:
    $result=$mcq[0]->correctAns($s_ans[0]);
    // the $s_ans[0] is the first answer submitted by the user, in the $s_ans array. 
    then i get the old error that says i'm calling a member function on a non-object.


    so what else do you suggest?

    thanks.
    Last edited by ASAAKI; 04-05-2003 at 08:36 PM.
    'If you don't stand for something, you'll fall for anything.'

  • #10
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Have you tried

    PHP Code:
    var_dump($_SESSION); 
    on the second page, and what does it report? Is there any data in the session at all?

    Further, you should not use session_register if you do also use $_SESSION. session_register was the way to register a session variable if you have register_globals turned on, and that is now outdated since the advent of the super-global $_SESSION array. Just treat $_SESSION as a normal array; there's no need to explicitly register session variables anymore. That's of course only true if you're running a php version >= 4.1 and register_globals is turned off.
    According to the manual, the use of both session registering approaches in one script can lead to unexpected and undeterminable behaviour - so better stick to one, in order to rule out the possiblity of this issue happening.

  • #11
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Two more things I just noticed:

    1. You use session_register incorrectly. This function expects strings of variable names instead of the variables themselves, see the manual. I would not be surprised if your session is totally empty on the second page.

    2. Better use isset($_SESSION['mcq']) rather than session_is_registered for the same reason why you shouldn't use session_register at all.

    Quoted from the manual:

    If you are using $_SESSION (or $HTTP_SESSION_VARS), do not use session_register(), session_is_registered() and session_unregister().
    http://www.php.net/manual/en/functio...n-register.php

    I know from my own experience that sessions can be a real PITA sometimes, but I'm optimistic that we solve your problems really soon.

  • #12
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    okay here's the report

    first let me tell you that the current lesson has 2 mcqs, so the array only has two objects.

    when i added "var_dump($_SESSION);" on the second page, without changing anything else, i did get a couple of lines of something mentioning "array(2)" and "Object", sorry i didn't manage to catch that, and when i changed the code i couldn't revert to the old one. but from what i understood of it, the session was holding an array, that did seem to have objects, which might have understood that were supposed to carry something, but they were all empty. perhaps only the structure got maintained.

    anyway, i changed the code then. got rid of session_is_registered, and just used $_SESSION directly. i got the same result, the lines i mentioned above.

    then, as per an example in that phpnet link, i used this on mcq1.php:
    PHP Code:
    /*old part -- just getting the mcq objects and stuff here */
    $no_mcqs=mysql_num_rows($result);
    for(
    $i=0;$i<mysql_num_rowS($result);$i++){
    $j=$i+1;
    $row_array=mysql_fetch_array($result);
    $id[$i]=$row_array[0];
    $mcq[$i]=new MCQ($id[$i]);
    $mcq[$i]->printQ($j);
    $mcq[$i]->printChoices($i);
    }
    /*here's the changed part */
    $mcqObjArray=serialize($mcq);
    $_SESSION['mcqObjArray'] = $mcqObjArray
    that's it.

    on mcq2.php i did this:
    PHP Code:
    $mcqObjArray=unserialize($_SESSION['mcqObjArray']); 
    after which, (this is the good part!) i got this session output:

    array(2) { ["mcq"]=> array(2) { [0]=> object(mcq)(10) { ["id"]=> string(3) "1.0" ["type"]=> string(8) "question" ["mark"]=> string(1) "1" ["question"]=> string(42) "Which of these answers is correct? (ans:C)" ["a"]=> string(16) "This is answer A" ["b"]=> string(16) "This is answer B" ["c"]=> string(16) "This is answer C" ["d"]=> string(16) "This is answer D" ["e"]=> string(16) "This is answer E" ["ans"]=> string(1) "C" } [1]=> object(mcq)(10) { ["id"]=> string(3) "2.0" ["type"]=> string(8) "question" ["mark"]=> string(1) "2" ["question"]=> string(42) "Which of these answers is correct? (ans:B)" ["a"]=> string(16) "This is answer A" ["b"]=> string(16) "This is answer B" ["c"]=> string(16) "This is answer C" ["d"]=> string(16) "This is answer D" ["e"]=> string(16) "This is answer E" ["ans"]=> string(1) "B" } } ["mcqObjArray"]=> string(658) "a:2:{i:0;O:3:"mcq":10:{s:2:"id";s:3:"1.0";s:4:"type";s:8:"question";s:4:"mark";s:1:"1";s:8:"questio n";s:42:"Which of these answers is correct? (ans:C)";s:1:"a";s:16:"This is answer A";s:1:"b";s:16:"This is answer B";s:1:"c";s:16:"This is answer C";s:1:"d";s:16:"This is answer D";s:1:"e";s:16:"This is answer E";s:3:"ans";s:1:"C";}i:1;O:3:"mcq":10:{s:2:"id";s:3:"2.0";s:4:"type";s:8:"question";s:4:"mark";s:1: "2";s:8:"question";s:42:"Which of these answers is correct? (ans:B)";s:1:"a";s:16:"This is answer A";s:1:"b";s:16:"This is answer B";s:1:"c";s:16:"This is answer C";s:1:"d";s:16:"This is answer D";s:1:"e";s:16:"This is answer E";s:3:"ans";s:1:"B";}}" }


    which means that this time the session stored everything all right! thank you thank you mordred!

    BUT, if i try to echo $mcq[0]->id i still get nothing, and if i try to use the correctAns function, i get the same old error:
    Fatal error: Call to a member function on a non-object in c:\phpdev\www\learning\mcq2.php on line 75


    'If you don't stand for something, you'll fall for anything.'

  • #13
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    oopsies, i'd been making this retarded mistake:

    $result=$mcq[0]->correctAns($s_ans[0]);

    instead of:

    $result=$mcqObjArray[0]->correctAns($s_ans[0]);



    it's all working now. thanks for all the help mordred!
    'If you don't stand for something, you'll fall for anything.'

  • #14
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Glad you sorted it out yourself, I really began to wonder if this was one of the strange cases session handling sometimes throws up, and which are different depending on the exact PHP version. From what I see of your posted code, I'd say it *should* also work without explicitly (de-)serializing the array of objects into the session, because that's how I do it usually and so far it worked ok for me.

    Care to tell us which PHP version you run exactly? Just so others might who experience the same symptoms can verify that your workaround does apply to them too.

  • #15
    Regular Coder
    Join Date
    Jul 2002
    Location
    This little Earth.
    Posts
    383
    Thanks
    0
    Thanked 0 Times in 0 Posts
    well i tried it. it *did* work without unserializing.
    i'm using PHP 4.2.3.
    'If you don't stand for something, you'll fall for anything.'


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •