Professional Web Applications Themes

Tricky problem with classes! - PHP Development

Problem: I try to store data in a objects field and read it out again. Sounds easy, yeah. But its a bit tricky here.... ;-) This is the class Customer.php with some setter and getter functions to store customers data within an object. It works. Furthermore, it includes a synchronize method, which calls the individual set function and takes the data from the $_POST or $_GET var. Therefore the fieldnames from the HTML form and objectfields have to be equal, so that data for $obj->fieldB can be found at $_GET['fieldB']. Well, no problem, yet. sample: $obj->synchronize("fieldA"); will call the function ...

  1. #1

    Default Tricky problem with classes!

    Problem: I try to store data in a objects field and read it out again.
    Sounds easy, yeah. But its a bit tricky here.... ;-)


    This is the class Customer.php with some setter and getter functions to
    store customers data within an object.
    It works.
    Furthermore, it includes a synchronize method, which calls the
    individual set function and takes the data
    from the $_POST or $_GET var.
    Therefore the fieldnames from the HTML form and objectfields have to be
    equal, so that data for $obj->fieldB
    can be found at $_GET['fieldB']. Well, no problem, yet.

    sample:
    $obj->synchronize("fieldA");

    will call the function setFieldA($_GET/POST['fieldA']) from
    the objects methods


    So this is the Customer.php (shortened to the basics we might need here):

    --CODE-----------------------------------------------

    ...

    // setter and getter of a class customer

    function getName()
    {
    return $this->name;
    }

    function setName($name)
    {
    if(strlen($id) <= 40) {
    $this->name = $name;
    return true;
    }
    else {
    return false;
    }
    }

    ...

    // $obj.synchronize calls the setter function set{$PARAM} of a class
    object, to fill the object with Data

    function synchronize($param, $method="POST")
    {
    $functionName = 'set'.ucfirst($param);
    if (method_exists($this, $functionName)) {
    $buf = null;
    if(strtoupper($method)=="POST") {
    $buf = $_POST[$param];
    }
    elseif(strtoupper($method)=="GET") {
    $buf = $_GET[$param];
    }

    if($buf <> null) {
    return call_user_func( array($this, $functionName), $buf );
    }
    else {
    return false;
    }
    }
    else {
    return false;
    }
    }

    ...


    -----------------------------------------------------

    Well. The class Customer.php itself works!
    But now, I try to send data to the object via the synchronize function.
    To do this, I use the following sample script, which receives data via
    method GET by URL as you can see:


    .../step2.php?name=JohnDoe


    --CODE-----------------------------------------------

    <?php

    include_once 'Customer.php';

    $newCust = new Customer();
    $method = "GET";

    if (!$newCust->synchronize("name",$method)) {
    printError( "Der Name ist nicht korrekt!");
    };

    print "Result: ".$newCust->getName();

    ?>


    ------------------------------------------------------

    Well thats all.
    It should send "JohnDoe" to the $newCust->name variable and print out:

    Result: JohnDoe

    But in fact, it prints: Result:


    To make it more clear what I need:
    The expected result could be reached by doing the following from the
    step2.php:

    $newCust->setName($_GET['name']);

    But I have so many fields and forms which change often, that this is not
    an effective way!
    I need to do this via my synchronize method, that calls the
    corresponding set function automatically.
    Well, the call of the function in the class itself works, but I cannot
    read the object's field at the end!
    I tried putting a >>print "test: $name"<< within the setName function
    and it seems to work correctly!
    So the value is sored somewhere, but I don'T know where it is stored!
    Maybe I write it to a wrong new object? is $this wrong? do I need to
    point to $parent?

    I hope anybody can help me!?

    Thanks in advance,
    Lars
    Lars Plessmann Guest

  2. #2

    Default Re: Tricky problem with classes!

    Lars Plessmann wrote:
    > function setName($name)
    > {
    > if(strlen($id) <= 40) {
    > $this->name = $name;
    > return true;
    > }
    > else {
    > return false;
    > }
    > }
    >
    > ...
    The snipper above does not specify the origin of $id (global, class
    property), so it will always resort to the else clause and therefore returns
    false.


    JW



    Janwillem Borleffs Guest

  3. #3

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > The snipper above does not specify the origin of $id (global, class
    > property), so it will always resort to the else clause and therefore
    > returns false.
    >
    Not entirely true, because when undefined, $id will be created with an empty
    value.

    Remove $id anyway, because it isn't used:

    function setName($name) {
    $this->name = $name;
    return true;
    }

    Use require_once instead of include_once to test if the class file has been
    included properly. Rather then include_once, require_once throws a fatal
    error when inclusion fails.

    Note: Always develop your code with the highest error_reporting level E_ALL.


    JW



    Janwillem Borleffs Guest

  4. #4

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Janwillem Borleffs wrote:
    >
    >>The snipper above does not specify the origin of $id (global, class
    >>property), so it will always resort to the else clause and therefore
    >>returns false.
    >>
    >
    >
    > Not entirely true, because when undefined, $id will be created with an empty
    > value.
    >
    > Remove $id anyway, because it isn't used:
    >
    > function setName($name) {
    > $this->name = $name;
    > return true;
    > }
    >
    > Use require_once instead of include_once to test if the class file has been
    > included properly. Rather then include_once, require_once throws a fatal
    > error when inclusion fails.
    >
    > Note: Always develop your code with the highest error_reporting level E_ALL.
    >
    >
    > JW
    >
    >
    >
    Yes. You are right. $id should be $name (i'm a copy paste fool *g*)
    I replaced include_once by require_once and error_reporting is set to E_ALL.
    But the bug still exists!

    By the way:


    --------------------
    function setName($name)
    {
    if(strlen($name) <= 40) {
    $this->name = $name;
    print "WRITTEN '$this->name' | ";
    return true;
    }
    else {
    return false;
    }
    }
    --------------------

    A call to setName($name) shows me "WRITTEN Testname | " if the $name is
    set to "Testname". So the setter itself seems to be okay!
    But after function synchronize the object could not store the value.
    I see this, when I make a $obj->getName().

    Same at the synch func. It goes to the step it should go:

    ----------------------
    function synchronize($param, $method="POST")
    {
    $functionName = 'set'.ucfirst($param);
    if (method_exists($this, $functionName)) {
    $buf = null;
    if(strtoupper($method)=="POST") {
    $buf = $_POST[$param];
    }
    elseif(strtoupper($method)=="GET") {
    $buf = $_GET[$param];
    }

    if($buf <> null) {
    print "OKAY / WAS EXECUTED! ";
    return call_user_func( array($this, $functionName), $buf );
    }
    else {
    return false;
    }
    }
    else {
    return false;
    }
    }
    --------------------------

    So a $obj->synchronize("name") call with the URI of ?name=Testname
    prints out the following text:

    OKAY / WAS EXECUTED! WRITTEN 'Testname' |

    So I think the code itself should be okay, but the data goe to a wrong
    object address? Might be this the bug? So that a getName() call does not
    bring he the expected data?


    thanks,
    Lars
    Lars Plessmann Guest

  5. #5

    Default Re: Tricky problem with classes!

    Lars Plessmann wrote:
    > So I think the code itself should be okay, but the data goe to a wrong
    > object address? Might be this the bug? So that a getName() call does
    > not bring he the expected data?
    >
    See if the following works for you, it does on my test environment:

    [url]http://www.jwscripts.com/playground/sync.phps[/url]


    JW



    Janwillem Borleffs Guest

  6. #6

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Lars Plessmann wrote:
    >
    >>So I think the code itself should be okay, but the data goe to a wrong
    >>object address? Might be this the bug? So that a getName() call does
    >>not bring he the expected data?
    >>
    >
    >
    > See if the following works for you, it does on my test environment:
    >
    > [url]http://www.jwscripts.com/playground/sync.phps[/url]
    >
    >
    > JW
    >
    >
    >
    when I call the script with
    [url]http://127.0.0.1:8081/metallboerse/step1.php?name=JohnDoe[/url]
    I get this message:
    ------------------
    Notice: Undefined property: name in C:\Programme\Apache
    Group\Apache2\htdocs\metallboerse\step1.php on line 8
    Result:
    ------------------

    so I added the $name to the class Customer.
    Now it runs without any error messages, but the result does not appear.
    its empty:
    -------------
    Result:
    ------------


    Maybe it's a register_globals=off problem, when it runs on your environment?
    it doesn't run on my env. properly.
    Result with the upper data should be:
    -------------
    Result: JohnDoe
    -------------


    Any idea?

    Lars
    Lars Plessmann Guest

  7. #7

    Default Re: Tricky problem with classes!

    Lars Plessmann wrote:
    > when I call the script with
    > [url]http://127.0.0.1:8081/metallboerse/step1.php?name=JohnDoe[/url]
    > I get this message:
    > ------------------
    > Notice: Undefined property: name in C:\Programme\Apache
    > Group\Apache2\htdocs\metallboerse\step1.php on line 8
    > Result:
    > ------------------
    Because $name isn't defined and set before getName() is called through the
    synchronize() method, you will indeed get this error when you start with
    calling setName().
    >
    > Maybe it's a register_globals=off problem, when it runs on your
    > environment? it doesn't run on my env. properly.
    I'm working with defaults, so register_globals is disabled. Does step1.php
    contain exactly the same code as the example?


    JW



    Janwillem Borleffs Guest

  8. #8

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Because $name isn't defined and set before getName() is called
    > through the synchronize() method, you will indeed get this error when
    > you start with calling setName().
    >
    Mixed up getName and setName here, this sentence should read:

    Because $name isn't defined and set before setName() is called
    through the synchronize() method, you will indeed get this error when
    you start with calling getName().


    JW




    Janwillem Borleffs Guest

  9. #9

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Lars Plessmann wrote:
    >
    >>when I call the script with
    >>[url]http://127.0.0.1:8081/metallboerse/step1.php?name=JohnDoe[/url]
    >>I get this message:
    >>------------------
    >>Notice: Undefined property: name in C:\Programme\Apache
    >>Group\Apache2\htdocs\metallboerse\step1.php on line 8
    >>Result:
    >>------------------
    >
    >
    > Because $name isn't defined and set before getName() is called through the
    > synchronize() method, you will indeed get this error when you start with
    > calling setName().
    >
    Yes, I know. I changed that and added $name to the class. Then its okay.
    >
    >>Maybe it's a register_globals=off problem, when it runs on your
    >>environment? it doesn't run on my env. properly.
    >
    >
    > I'm working with defaults, so register_globals is disabled. Does step1.php
    > contain exactly the same code as the example?
    >
    >
    > JW
    >
    >
    >
    Okay. I'm working with defaults too. Only few changed for gd lib were
    neccessairy, but thats not the point, I think.

    i started your script (after adding $name to the Customer class) via
    browser by

    [url]http://127.0.0.1:8081/step1.php?name=JohnDoe[/url]

    but there is no result at the end.
    I get

    Result:

    instead of

    Result: JohnDoe



    Lars
    Lars Plessmann Guest

  10. #10

    Default Re: Tricky problem with classes!

    Lars Plessmann wrote:
    > i started your script (after adding $name to the Customer class) via
    > browser by
    >
    > [url]http://127.0.0.1:8081/step1.php?name=JohnDoe[/url]
    >
    > but there is no result at the end.
    Weird, the example works for me on both PHP 4.3 and PHP 5 default
    installations as it should...

    Does it work when you skip the synchronize method and call setName directly?


    JW



    Janwillem Borleffs Guest

  11. #11

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Janwillem Borleffs wrote:
    >
    >>Because $name isn't defined and set before getName() is called
    >>through the synchronize() method, you will indeed get this error when
    >>you start with calling setName().
    >>
    >
    >
    > Mixed up getName and setName here, this sentence should read:
    >
    > Because $name isn't defined and set before setName() is called
    > through the synchronize() method, you will indeed get this error when
    > you start with calling getName().
    >
    >
    > JW
    >
    >
    >
    >
    but I defined it in the class now, and it doesn't work:


    <?

    class Customer {

    var $name; // now its defined :-)

    function getName() {
    return $this->name;
    }

    function setName($name) {
    $this->name = $name;
    return true;
    }

    function synchronize($param, $method="POST") {
    $functionName = 'set'.ucfirst($param);
    if (method_exists($this, $functionName)) {
    $buf = null;
    if(strtoupper($method)=="POST") {
    $buf = $_POST[$param];
    } elseif(strtoupper($method)=="GET") {
    $buf = $_GET[$param];
    }

    if($buf <> null) {
    return call_user_func( array($this, $functionName), $buf );
    } else {
    return false;
    }
    } else {
    return false;
    }
    }
    }

    $newCust = new Customer();
    $method = "GET";

    if (!$newCust->synchronize("name",$method)) {
    print "Der Name ist nicht korrekt!";
    };

    print "Result: ".$newCust->getName();

    ?>
    Lars Plessmann Guest

  12. #12

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Lars Plessmann wrote:
    >
    >>i started your script (after adding $name to the Customer class) via
    >>browser by
    >>
    >>[url]http://127.0.0.1:8081/step1.php?name=JohnDoe[/url]
    >>
    >>but there is no result at the end.
    >
    >
    > Weird, the example works for me on both PHP 4.3 and PHP 5 default
    > installations as it should...
    >
    > Does it work when you skip the synchronize method and call setName directly?
    >
    >
    > JW
    >
    >
    >
    Yes. That works:

    $newCust->setName("JohnDoe");

    returns as expected:

    Result: JohnDoe


    it's tricky, isn't it!?
    Lars Plessmann Guest

  13. #13

    Default Re: Tricky problem with classes!

    Lars Plessmann wrote:
    > Yes. That works:
    >
    > $newCust->setName("JohnDoe");
    >
    > returns as expected:
    >
    > Result: JohnDoe
    >
    >
    > it's tricky, isn't it!?
    I see what the problem is. When calling call_user_func within a class, the
    object must be passed by reference in PHP 4.3. In PHP 5 it works both ways.

    So the fix is to change the following line:

    return call_user_func( array($this, $functionName), $buf );

    into:

    return call_user_func( array(&$this, $functionName), $buf );


    JW




    Janwillem Borleffs Guest

  14. #14

    Default Re: Tricky problem with classes!

    Janwillem Borleffs wrote:
    > Lars Plessmann wrote:
    >
    >>Yes. That works:
    >>
    >>$newCust->setName("JohnDoe");
    >>
    >>returns as expected:
    >>
    >>Result: JohnDoe
    >>
    >>
    >>it's tricky, isn't it!?
    >
    >
    > I see what the problem is. When calling call_user_func within a class, the
    > object must be passed by reference in PHP 4.3. In PHP 5 it works both ways.
    >
    > So the fix is to change the following line:
    >
    > return call_user_func( array($this, $functionName), $buf );
    >
    > into:
    >
    > return call_user_func( array(&$this, $functionName), $buf );
    >
    >
    > JW
    >
    >
    >
    >
    Yeah!!!!!!!!!!
    You seem to be a real php guru :)
    I thank you very much....

    (by the way I thought about that, but I changd both $this to &$this and
    that didn't work)


    Lars
    Lars Plessmann Guest

Similar Threads

  1. A tricky query problem
    By quiero mas in forum Coldfusion Database Access
    Replies: 2
    Last Post: November 12th, 07:17 AM
  2. Tricky SOAP input problem; need help with cfinvokesyntax
    By afrinl in forum Coldfusion - Advanced Techniques
    Replies: 3
    Last Post: April 6th, 02:36 AM
  3. Tricky problem with WebControl vs. Panel
    By Ovidiu Birladeanu via .NET 247 in forum ASP.NET Building Controls
    Replies: 1
    Last Post: September 20th, 10:02 AM
  4. tricky disable button problem
    By sid vishus in forum Macromedia Flash Actionscript
    Replies: 1
    Last Post: March 4th, 07:58 PM
  5. problem with actionscript 2.0 classes
    By findapollo in forum Macromedia Flash Actionscript
    Replies: 0
    Last Post: February 15th, 01:12 AM

Bookmarks

Posting Permissions

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139