Instantiate subclass depending on string value

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • grossespinne@gmail.com

    Instantiate subclass depending on string value

    Hi everybody!
    I have been thinking over the following problem:
    there are three classes: PageBase, which is the base class, PageA and
    PageB which are the subclasses of PageBase.
    In the index.php file I have a variable which I like to hold either an
    instance of PageA or PageB depending on the query string that is
    passed to index.php (e.g: if I get the query index.php?conte nt=a, I
    need an instance of PageA, but if I get the query: index.php?
    content=b, an instance of PageB is needed)

    Until now I found two solutions, but I am not satisfied with either of
    them:
    - use a switch structure
    - or use eval:

    $pageType = isset($_GET["page"]) ? $_GET["page"] : "PageBase";
    $thePage = eval("return new $pageType();");

    My question is whether a more object-oriented way exists to solve the
    problem.

    TIA

  • =?ISO-8859-15?Q?Iv=E1n_S=E1nchez_Ortega?=

    #2
    Re: Instantiate subclass depending on string value

    grossespinne@gm ail.com wrote:
    My question is whether a more object-oriented way exists to solve the
    problem.
    You are looking for a Factory design pattern.

    I suggest you to do a bit of research about that, and about design patterns
    in general.

    --
    ----------------------------------
    Iván Sánchez Ortega -ivansanchez-algarroba-escomposlinux-punto-org-


    Proudly running Debian Linux with 2.6.20-1-amd64 kernel, KDE 3.5.7, and PHP
    5.2.3-1 generating this signature.
    Uptime: 00:53:56 up 7 days, 8:24, 3 users, load average: 0.78, 0.67, 0.71

    Comment

    • Malcolm Dew-Jones

      #3
      Re: Instantiate subclass depending on string value

      grossespinne@gm ail.com wrote:
      : Hi everybody!
      : I have been thinking over the following problem:
      : there are three classes: PageBase, which is the base class, PageA and
      : PageB which are the subclasses of PageBase.
      : In the index.php file I have a variable which I like to hold either an
      : instance of PageA or PageB depending on the query string that is
      : passed to index.php (e.g: if I get the query index.php?conte nt=a, I
      : need an instance of PageA, but if I get the query: index.php?
      : content=b, an instance of PageB is needed)

      : Until now I found two solutions, but I am not satisfied with either of
      : them:
      : - use a switch structure
      : - or use eval:

      : $pageType = isset($_GET["page"]) ? $_GET["page"] : "PageBase";
      : $thePage = eval("return new $pageType();");

      : My question is whether a more object-oriented way exists to solve the
      : problem.

      No, that's one of the dirty little secrets of OOPs programming.
      Somewhere you have to do what you do above, either something like a
      switch, if/then/else, or as in your case something like an eval.

      (BTW: I would recommend a switch (or if/then/else) over eval because that
      prevents any chance of code injection. What if "page" is set to a string
      like "system('rm /*');" which probably wouldn't run in your code, but
      shows what I am getting at. You don't want to put that in your eval().)


      However you normally hide the dirty details in a "factory" class that
      returns an instance of the _base_ class. (In php that won't make much
      difference, as long as each class implements the same methods then all is
      ok, in a language like Java it must explicitly be the base class.)

      (my syntax correct! I haven't used php for a little while).

      $thePage = PageFactory->createPage( $pageType );

      later, when you say

      $thePage->someMethod($va r1,$vars) ;

      then either
      PageA->someMethod
      runs or
      PageB->someMethod
      runs.


      PageFactory is a class that you create. In this case it has one static
      method that returns PageBase. The code is something like (my syntax is
      not valid php today)

      function createPage ( $type ) returns PageBase

      if ($type = 'A') return (PageBase) new PageA();

      elsif ($type = 'B') return (PageBase) new PageB();

      else die "$type is not a known type of page";

      end function

      Comment

      • Rik

        #4
        Re: Instantiate subclass depending on string value

        On Sat, 23 Jun 2007 00:18:56 +0200, <grossespinne@g mail.comwrote:
        Hi everybody!
        I have been thinking over the following problem:
        there are three classes: PageBase, which is the base class, PageA and
        PageB which are the subclasses of PageBase.
        In the index.php file I have a variable which I like to hold either an
        instance of PageA or PageB depending on the query string that is
        passed to index.php (e.g: if I get the query index.php?conte nt=a, I
        need an instance of PageA, but if I get the query: index.php?
        content=b, an instance of PageB is needed)
        >
        Until now I found two solutions, but I am not satisfied with either of
        them:
        - use a switch structure
        - or use eval:
        >
        $pageType = isset($_GET["page"]) ? $_GET["page"] : "PageBase";
        $thePage = eval("return new $pageType();");
        First of all, what is wrong with dropping the eval, and just creating
        objects on the fly? So:

        $pageType = (isset($_GET['page'] &&
        class_exists('P age'.strtoupper ($_GET['page'][1]) ? 'Page'.$_GET['page'][1]
        : 'PageBase';
        $thePage = new $pageType();
        My question is whether a more object-oriented way exists to solve the
        problem.
        Indeed, like others said, check Factory patterns.
        --
        Rik Wasmus

        Comment

        • Jerry Stuckle

          #5
          Re: Instantiate subclass depending on string value

          grossespinne@gm ail.com wrote:
          Hi everybody!
          I have been thinking over the following problem:
          there are three classes: PageBase, which is the base class, PageA and
          PageB which are the subclasses of PageBase.
          In the index.php file I have a variable which I like to hold either an
          instance of PageA or PageB depending on the query string that is
          passed to index.php (e.g: if I get the query index.php?conte nt=a, I
          need an instance of PageA, but if I get the query: index.php?
          content=b, an instance of PageB is needed)
          >
          Until now I found two solutions, but I am not satisfied with either of
          them:
          - use a switch structure
          - or use eval:
          >
          $pageType = isset($_GET["page"]) ? $_GET["page"] : "PageBase";
          $thePage = eval("return new $pageType();");
          >
          My question is whether a more object-oriented way exists to solve the
          problem.
          >
          TIA
          >
          Not every statement has to be object oriented. That's why PHP still has
          switch statements. It's what I would do.

          There are other ways to do it, i.e. factories. But I also believe in KISS.

          --
          =============== ===
          Remove the "x" from my email address
          Jerry Stuckle
          JDS Computer Training Corp.
          jstucklex@attgl obal.net
          =============== ===

          Comment

          • grossespinne@gmail.com

            #6
            Re: Instantiate subclass depending on string value

            On Jun 23, 4:14 am, Jerry Stuckle <jstuck...@attg lobal.netwrote:
            grossespi...@gm ail.com wrote:
            Hi everybody!
            I have been thinking over the following problem:
            there are three classes: PageBase, which is the base class, PageA and
            PageB which are the subclasses of PageBase.
            In the index.php file I have a variable which I like to hold either an
            instance of PageA or PageB depending on the query string that is
            passed to index.php (e.g: if I get the query index.php?conte nt=a, I
            need an instance of PageA, but if I get the query: index.php?
            content=b, an instance of PageB is needed)
            >
            Until now I found two solutions, but I am not satisfied with either of
            them:
            - use a switch structure
            - or use eval:
            >
            $pageType = isset($_GET["page"]) ? $_GET["page"] : "PageBase";
            $thePage = eval("return new $pageType();");
            >
            My question is whether a more object-oriented way exists to solve the
            problem.
            >
            TIA
            >
            Not every statement has to be object oriented. That's why PHP still has
            switch statements. It's what I would do.
            >
            There are other ways to do it, i.e. factories. But I also believe in KISS.
            >
            --
            =============== ===
            Remove the "x" from my email address
            Jerry Stuckle
            JDS Computer Training Corp.
            jstuck...@attgl obal.net
            =============== ===
            Thanks to everybody for your help. I think I am going to use the
            Factory method and implement it with the solution suggested by Rik.

            Comment

            Working...