2

I have a simple example of PHP sessions and AJAX, which works when holding an array in session:

Request file:

<?php
    session_start();
    $_SESSION['data'] = array('foo','bar');
    echo count($_SESSION['data']);
?>
<html>
<head>
    <title>Test</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
</head>
<body>
    <button id="but1">Go</button>
    <script type="text/javascript">
        $('#but1').click(function() {
            $.ajax({
                url:'ajaxtest_remote.php',
                success:function(result) {
                    alert(result);
                }
            });
        });
    </script>
</body>
</html>

Remote file:

<?php
    session_start();
    echo 'count=' . count($_SESSION['data']);
?>

The echo on the first file shows 2, and the alert in the success function displays "count=2". Happy days.

Where the problem happens is if I swap my array for a class object:

Request File:

<?php
    session_start();
    include('ajaxtest_class.php');
    $_SESSION['obj'] = new TestClass('foo,bar');
    echo count($_SESSION['obj']->dataList);
?>
<!-- HMTL AS ABOVE -->

Remote File:

<?php
    session_start();
    echo 'count=' . count($_SESSION['obj']->dataList);
?>

Class File:

<?php
    class TestClass {
        var $dataList;
        function TestClass($incoming) {
            $this->dataList = explode(',',$incoming);
        }
    }
?>

This still displays a 2 on the first page, but the ajax success alert comes back "count=0". Can anyone explain why this is?

Update1

If I import the class file into remote it still doesn't work, although I can prove the class is loaded.

<?php
    session_start();
    include('ajaxtest_class.php');
    $c = new TestClass('a,b,c');
    echo 'count=' . count($_SESSION['obj']->dataList) . '-' . count($c->dataList);
?>

The new alert from the ajax success reads count=0-3.

Update2

var_dump($_SESSION['obj']);

object(__PHP_Incomplete_Class)#8 (2) {
    ["__PHP_Incomplete_Class_Name"]=>
    string(9) "TestClass"
    ["dataList"]=>
    array(2) {
        [0]=>
        string(3) "foo"
        [1]=>
        string(3) "bar"
    }
}
netcoder
  • 66,435
  • 19
  • 125
  • 142
shanethehat
  • 15,460
  • 11
  • 57
  • 87
  • try to debug it both times with a `var_dump`. are you on an old php4 ? or why do you write your classes like this. php5 way would be to have a `function __construct($incoming)` – Rufinus Jun 09 '11 at 14:07
  • I don't get to try oop PHP very often, still very much a novice! So I should just replace the name of my constructor with `_construct`? – shanethehat Jun 09 '11 at 14:19

1 Answers1

6

You would need to include the Class in the remote_ajax file (before session_start()):

edit: The serialize/unserialize requirement is a limitation of PHP4.

Request file:

<?php
include('ajaxtest_class.php');
session_start();
$_SESSION['obj'] = serialize(new TestClass('foo,bar'));

Remote file:

<?php
    session_start();
    include('ajaxtest_class.php');
    $obj = unserialize($_SESSION['obj']);
    echo 'count=' . count($obj->dataList);
?>

In PHP, the class constructor should be defined differently:

<?php
    class TestClass {
        var $dataList;
        function __construct($incoming) {
            $this->dataList = explode(',',$incoming);
        }
    }
?>
Fosco
  • 38,138
  • 7
  • 87
  • 101
  • +1 Indeed, unless the class is loaded, it will be a __PHP_Incomplete_Class with no dataList property. – netcoder Jun 09 '11 at 14:09
  • I've made the adjustment exactly as above, but still get `count=0` – shanethehat Jun 09 '11 at 14:20
  • @shanethehat I posted a quick troubleshooting step.. what does var_dump return? – Fosco Jun 09 '11 at 14:28
  • Thanks, I've updated the question with the output. It is an incomplete class, even after importing the class file. – shanethehat Jun 09 '11 at 14:37
  • @shanethehat I've updated the answer after doing further research. Please give this a shot. – Fosco Jun 09 '11 at 14:42
  • @Fosco - Bravo, that's nailed it. Thank you! – shanethehat Jun 09 '11 at 14:54
  • @shanethehat: By the way, don't serialize objects or arrays when putting them in session. It's extra overhead and is completely useless. – netcoder Jun 09 '11 at 19:24
  • @Fosco: I've never came across a use case when that was actually required. Session data is already serialized as far as I know. You have an example? – netcoder Jun 09 '11 at 19:28
  • @netcoder You're looking at one right now. The OPs example would not work without serialize/unserialize... adding it fixed it, no other changes. – Fosco Jun 09 '11 at 19:29
  • @Fosco: I run this code without serialization and it works fine... The code is PHP4. Could this be a limitation? I haven't use PHP4 in ages... – netcoder Jun 09 '11 at 19:33
  • @netcoder that may be it... either way, the OPs issue is resolved. – Fosco Jun 09 '11 at 19:35
  • @Fosco: Actually [it is a limitation of PHP4](http://php.net/manual/en/oop4.serialization.php). I think you should mention it in your post, because PHP5 users (99.9999%) may not understand the point. :) – netcoder Jun 09 '11 at 19:35
  • @netcoder: I'm running on 5.2.1, although the class code is a little antiquated. Do I just need to replace the name of my constructor as suggested in Rufinus's comment, or are you saying that the code in my post works fine for you as long as the class file is included? – shanethehat Jun 09 '11 at 22:25
  • @shanethehat I had not run the code myself, or noticed Rufinus's comment... no harm in trying it, for sure. – Fosco Jun 09 '11 at 22:27
  • @fosco: I just did, removing the serialisation and changing `function TestClass(` to `function __construct(` breaks it again. Replacing the serialisation fixes it again. I'm on a shared hosting provider, I wonder if this could be caused by something in their setup? – shanethehat Jun 09 '11 at 22:35
  • @shanethehat I suppose... but hey, it works with serialize, so go with it. – Fosco Jun 09 '11 at 22:37
  • 1
    I've figured it out. You must include the class file **before** calling session_start(). Makes sense I suppose. – shanethehat Jun 10 '11 at 10:25
  • @shanethehat well done.. I updated the answer to include that. – Fosco Jun 10 '11 at 13:23