Problems with include and duplication function definitions

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Wescotte

    Problems with include and duplication function definitions

    I have an application that uses several file formats for similar data.
    So I've created various php files for each format containing the same
    functions which produce the same end result.

    Now I currently have a functions setup that just reads a file and
    determines which file type it is and includes the correct source. My
    goal is add a new function to each source called
    My_File_Format( $filename) where each file checks to see if the
    specified file is the format it knows how to work with.

    The problem I'm running into is duplicate function names. Here is a
    test case of what exactly I was attempting to do. Anyone know how to
    actually get this to work?


    Output:
    Test1
    Fatal error: Cannot redeclare test_case() (previously declared in
    C:\Inetpub\Acco unting\test1.ph p:5) in C:\Inetpub\Acco unting\test2.ph p
    on line 6

    Assumed should be
    Test1Test2

    file testcase.php
    <html>
    <body>
    <?php

    class file_format
    {
    var $f;
    function file_format($fi lename)
    {
    $this->f = $filename;
    }
    function is_format()
    {
    include "$this->f";
    test_case();
    }
    }

    $a = new file_format("te st1.php");
    $b = new file_format("te st2.php");
    $a->is_format();
    $b->is_format();

    return;


    ?>
    </body>
    </html>

    file: test1.php
    <?php

    function test_case()
    {
    echo "Test1";
    }
    ?>

    file: test2.php
    <?php

    function test_case()
    {
    echo "Test2";
    }
    ?>

  • Colin McKinnon

    #2
    Re: Problems with include and duplication function definitions

    Wescotte wrote:
    [color=blue]
    > I have an application that uses several file formats for similar data.
    > So I've created various php files for each format containing the same
    > functions which produce the same end result.
    >[/color]
    <snip>
    [color=blue]
    >
    > The problem I'm running into is duplicate function names. Here is a
    > test case of what exactly I was attempting to do. Anyone know how to
    > actually get this to work?
    >
    > Output:
    > Test1
    > Fatal error: Cannot redeclare test_case() (previously declared in
    > C:\Inetpub\Acco unting\test1.ph p:5) in C:\Inetpub\Acco unting\test2.ph p
    > on line 6[/color]

    Sorry Wescotte - while many people bemoan the lack of namespaces in PHP,
    really this is just sloppy programming. If you are applying a procedural
    methodology then you should be planning your program better - while you
    might have deliberately chosen the same naming strategy for different the
    functions in different include files - there's something wrong if it's
    including more than one. In fairness, this is a very common mistake, and
    one of the reasons for object oriented programming (which obviates such
    eventualities).

    So I guess the solutions are:
    1) look at your flow of control - only include one file
    2) or learn OO.

    C.


    Comment

    • Wescotte

      #3
      Re: Problems with include and duplication function definitions

      The application is processing freight EDI files. We have mutliple
      vendors who use various file formats. The goal was to create an easy
      way for somebody else to add new vendors without having to mess with
      the base code.

      So they create a php file to with 3 functions

      1. Check if the specified file is from that vendor
      2. Parse the invoice data
      3. Build remittance EDI files

      So I'd have a table that would contain
      Vendor # for our ERP/PHP file to include

      If they wanted to add additional suport they would create a new PHP
      file with the 3 functions I described and add an entry into the above
      table

      If you have a better suggestion on how to allow for such a task please
      let me know


      The current method is a global detect function that knows what files to
      include, a global creation file that knows which files to include based
      on detected type and a global remittance function that knows which file
      to include based on the vendor #.

      So if somebody wants to add a new vendor they have to append their
      detection code and add code to all 3 functions. Granted it's only a few
      lines each it's still something I'd prefer they didn't have to do.

      Comment

      • Jerry Stuckle

        #4
        Re: Problems with include and duplication function definitions

        Wescotte wrote:[color=blue]
        > The application is processing freight EDI files. We have mutliple
        > vendors who use various file formats. The goal was to create an easy
        > way for somebody else to add new vendors without having to mess with
        > the base code.
        >
        > So they create a php file to with 3 functions
        >
        > 1. Check if the specified file is from that vendor
        > 2. Parse the invoice data
        > 3. Build remittance EDI files
        >
        > So I'd have a table that would contain
        > Vendor # for our ERP/PHP file to include
        >
        > If they wanted to add additional suport they would create a new PHP
        > file with the 3 functions I described and add an entry into the above
        > table
        >
        > If you have a better suggestion on how to allow for such a task please
        > let me know
        >
        >
        > The current method is a global detect function that knows what files to
        > include, a global creation file that knows which files to include based
        > on detected type and a global remittance function that knows which file
        > to include based on the vendor #.
        >
        > So if somebody wants to add a new vendor they have to append their
        > detection code and add code to all 3 functions. Granted it's only a few
        > lines each it's still something I'd prefer they didn't have to do.
        >[/color]

        Yes - learn OO programming.

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

        Comment

        • Wescotte

          #5
          Re: Problems with include and duplication function definitions

          Can you be more specific? I believe I understand the OO programming and
          how to use classes (and inheritance) but I fail ot see how I can allow
          a class to have the same function name and yet completely different
          code.

          Comment

          • Jerry Stuckle

            #6
            Re: Problems with include and duplication function definitions

            Wescotte wrote:[color=blue]
            > Can you be more specific? I believe I understand the OO programming and
            > how to use classes (and inheritance) but I fail ot see how I can allow
            > a class to have the same function name and yet completely different
            > code.
            >[/color]

            OK, stop thinking in functions. Think in objects.

            Each type of file is a different type of object. Each will have it's own class
            to do the processing. And every one of the classes can have the same function
            names - but different code.

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

            Comment

            • Wescotte

              #7
              Re: Problems with include and duplication function definitions

              Yes, I understand that but I still fail to see how to make it all work.

              If I have a base edi file class and a class for each type that inherits
              the base class that contains the 3 functions mentioned above I'd still
              need do have something like

              $query = "select class_name, class_source from class_list";
              $result = odbc_exec($conn ection, $query);

              $done = false;

              while (odbc_fetch_row ($result) || $done) {
              include odbc_result($re sult, "class_source") ;
              $test_case = new odbc_result($re sult, "class_name "); // I can't
              see this working but I haven't specifcally tested it yet
              if ($test_case.Kno wn_File_Format( $fillename)) {
              $test_case.Pars e_file($filenam e);
              $done = true;
              }
              }


              Again, the whole purpose of this was to allow a user to add additional
              EDI file formats (and code to process them) without acessing any code.
              Maybe I'm missing something obvious but I can't think my way around how
              to actually get this to work without hard coding the source names/class
              names.

              Comment

              • Jerry Stuckle

                #8
                Re: Problems with include and duplication function definitions

                Wescotte wrote:[color=blue]
                > Yes, I understand that but I still fail to see how to make it all work.
                >
                > If I have a base edi file class and a class for each type that inherits
                > the base class that contains the 3 functions mentioned above I'd still
                > need do have something like
                >
                > $query = "select class_name, class_source from class_list";
                > $result = odbc_exec($conn ection, $query);
                >
                > $done = false;
                >
                > while (odbc_fetch_row ($result) || $done) {
                > include odbc_result($re sult, "class_source") ;
                > $test_case = new odbc_result($re sult, "class_name "); // I can't
                > see this working but I haven't specifcally tested it yet
                > if ($test_case.Kno wn_File_Format( $fillename)) {
                > $test_case.Pars e_file($filenam e);
                > $done = true;
                > }
                > }
                >
                >
                > Again, the whole purpose of this was to allow a user to add additional
                > EDI file formats (and code to process them) without acessing any code.
                > Maybe I'm missing something obvious but I can't think my way around how
                > to actually get this to work without hard coding the source names/class
                > names.
                >[/color]

                No, you include all the class sources at the beginning. Then you instantiate
                the appropriate one as you need it, i.e.

                while (odbc_fetch_row ($result) || $done) {
                // Get the file format here, then
                $myObject = null;
                switch($fileFor mat) {
                case "format1" :
                $myObject = new MyClass1();
                break;
                case "format2":
                $myObject = new MyClass2();
                break;
                // etc.
                }
                if (myObject) {
                $myObject->doSomething($o dbc_result); // Call function(s) in the class
                }

                Each class will handle one file format and all classes will have the same
                function names. Just determine the file format, instantiate the appropriate
                class and let it do the work.

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

                Comment

                • Wescotte

                  #9
                  Re: Problems with include and duplication function definitions

                  That is exactly what I did in my current version but I wanted a cleaner
                  method.

                  In the case you described above I would have to have to modify multiple
                  sectiosn of code to add a new class type instead of simply adding a new
                  row to a table that contains the code for a new type. I guess the only
                  method I can see would be again going by functions but having a prefix
                  to each say

                  Fedex.php
                  Fedex_Detected_ EDI_Type()
                  Fedex_Parse_EDI _File();
                  Fedex_Create_Re mittance()

                  DHL.php
                  DHL_Detected_ED I_Type()
                  DHL_Parse_EDI_F ile()
                  DHL_Create_Remi ttance()

                  while (odbc_fetch_row ($result) || $done) {
                  $function = odbc_result($re sult, "name") . "_Detected_EDI_ Type";
                  if ($function()) {
                  // Detected edi file format
                  // do something....
                  $done = true;
                  }
                  }

                  With this method I can create a table that contains the source code
                  filename
                  and the leading characters into the function name so that each name is
                  unique

                  Now to add a new type I simply add a new record ot the table rather
                  than adding a new case "formatX": instance in the detcting/pasing and
                  creating remittance sections
                  which allows me to isolate the code from the user yet allow them to
                  create code for new file types

                  While this method will work I was looking for a way to keep the
                  function names identically instead of having a leading unique string +
                  function name (Fedex or DHL) _Detected_EDI_T ype

                  Basically I was looking for the ability to include "code.php" and then
                  somehow uninclude it after I used it.

                  Comment

                  • David Haynes

                    #10
                    Re: Problems with include and duplication function definitions

                    Wescotte wrote:[color=blue]
                    > That is exactly what I did in my current version but I wanted a cleaner
                    > method.
                    >
                    > In the case you described above I would have to have to modify multiple
                    > sectiosn of code to add a new class type instead of simply adding a new
                    > row to a table that contains the code for a new type. I guess the only
                    > method I can see would be again going by functions but having a prefix
                    > to each say
                    >
                    > Fedex.php
                    > Fedex_Detected_ EDI_Type()
                    > Fedex_Parse_EDI _File();
                    > Fedex_Create_Re mittance()
                    >
                    > DHL.php
                    > DHL_Detected_ED I_Type()
                    > DHL_Parse_EDI_F ile()
                    > DHL_Create_Remi ttance()
                    >
                    > while (odbc_fetch_row ($result) || $done) {
                    > $function = odbc_result($re sult, "name") . "_Detected_EDI_ Type";
                    > if ($function()) {
                    > // Detected edi file format
                    > // do something....
                    > $done = true;
                    > }
                    > }
                    >
                    > With this method I can create a table that contains the source code
                    > filename
                    > and the leading characters into the function name so that each name is
                    > unique
                    >
                    > Now to add a new type I simply add a new record ot the table rather
                    > than adding a new case "formatX": instance in the detcting/pasing and
                    > creating remittance sections
                    > which allows me to isolate the code from the user yet allow them to
                    > create code for new file types
                    >
                    > While this method will work I was looking for a way to keep the
                    > function names identically instead of having a leading unique string +
                    > function name (Fedex or DHL) _Detected_EDI_T ype
                    >
                    > Basically I was looking for the ability to include "code.php" and then
                    > somehow uninclude it after I used it.
                    >[/color]

                    I don't see why you would need to do apply special naming when the
                    object will encapsulate that for you.

                    If you have a column in the DB table called something like 'class_name',
                    then I think you could do something like:

                    while( odbc_fetch_row( $result) || $done ) {
                    $class_name = odbc_result($re sult, 'class_name');
                    if( $obj = new $class_name() ) {
                    // call whatever method you need
                    $obj->Detected_EDI_T ype();
                    $obj->Parse_EDI_File ();
                    $obj->Create_Remitta nce();
                    }
                    }

                    -david-

                    Comment

                    • Jerry Stuckle

                      #11
                      Re: Problems with include and duplication function definitions

                      Wescotte wrote:[color=blue]
                      > That is exactly what I did in my current version but I wanted a cleaner
                      > method.
                      >
                      > In the case you described above I would have to have to modify multiple
                      > sectiosn of code to add a new class type instead of simply adding a new
                      > row to a table that contains the code for a new type. I guess the only
                      > method I can see would be again going by functions but having a prefix
                      > to each say
                      >
                      > Fedex.php
                      > Fedex_Detected_ EDI_Type()
                      > Fedex_Parse_EDI _File();
                      > Fedex_Create_Re mittance()
                      >
                      > DHL.php
                      > DHL_Detected_ED I_Type()
                      > DHL_Parse_EDI_F ile()
                      > DHL_Create_Remi ttance()
                      >
                      > while (odbc_fetch_row ($result) || $done) {
                      > $function = odbc_result($re sult, "name") . "_Detected_EDI_ Type";
                      > if ($function()) {
                      > // Detected edi file format
                      > // do something....
                      > $done = true;
                      > }
                      > }
                      >
                      > With this method I can create a table that contains the source code
                      > filename
                      > and the leading characters into the function name so that each name is
                      > unique
                      >
                      > Now to add a new type I simply add a new record ot the table rather
                      > than adding a new case "formatX": instance in the detcting/pasing and
                      > creating remittance sections
                      > which allows me to isolate the code from the user yet allow them to
                      > create code for new file types
                      >
                      > While this method will work I was looking for a way to keep the
                      > function names identically instead of having a leading unique string +
                      > function name (Fedex or DHL) _Detected_EDI_T ype
                      >
                      > Basically I was looking for the ability to include "code.php" and then
                      > somehow uninclude it after I used it.
                      >[/color]

                      The only code you would have to change would be that in the switch() statement -
                      and that could be an included file. Alternatively, you could do as David suggested.

                      Remember - the user won't be able to just add a new type. Someone's going to
                      have to write a class for that type, also. So along with adding the class, you
                      could just add the new type to the switch() statement.

                      Alternatively, you could place the switch statement in a static function in the
                      base class, i.e.

                      class BaseClass {
                      static function getType($filefo rmat) {
                      switch($fileFor mat) {
                      case "format1" :
                      return new MyClass1();
                      case "format2":
                      return new MyClass2();
                      // etc.
                      default:
                      return null;
                      }
                      }
                      }

                      Then you only need to change the base class.

                      Another alternative would be to have each class check to see what it can handle
                      via static functions, and ask it, i.e.

                      class DerivedClass1 {
                      static function CanIHandeThis ($fileFormat) {
                      return $fileFormat == 'FedEx';
                      }
                      }

                      But you would still need to have an array of the various types someplace (i.e. a
                      common base class). The advantage here is you've moved class-specific code to
                      the derived classes themselves. And you could still have the switch class in
                      your base class.


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

                      Comment

                      • Wescotte

                        #12
                        Re: Problems with include and duplication function definitions

                        Yeah, I didn't realize you could do new $class_name();

                        I think this will be the method I use

                        Comment

                        • Wescotte

                          #13
                          Re: Problems with include and duplication function definitions

                          Sure, but I prefer to find a method that allows for virtually no
                          modification to the original code.

                          I do prefer to use the method David suggested. I wasn't aware I could
                          do something like $new_class = new $class_name_str ing;

                          I'd also like to thank you guys for all the help

                          Comment

                          • Jerry Stuckle

                            #14
                            Re: Problems with include and duplication function definitions

                            Wescotte wrote:[color=blue]
                            > Sure, but I prefer to find a method that allows for virtually no
                            > modification to the original code.
                            >
                            > I do prefer to use the method David suggested. I wasn't aware I could
                            > do something like $new_class = new $class_name_str ing;
                            >
                            > I'd also like to thank you guys for all the help
                            >[/color]

                            The only problem might be - I don't know if you can do it directly. You may
                            have to do something like

                            $myObject = eval(new $className);

                            Never tried it either way, though.

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

                            Comment

                            • David Haynes

                              #15
                              Re: Problems with include and duplication function definitions

                              Jerry Stuckle wrote:[color=blue]
                              > Wescotte wrote:[color=green]
                              >> Sure, but I prefer to find a method that allows for virtually no
                              >> modification to the original code.
                              >>
                              >> I do prefer to use the method David suggested. I wasn't aware I could
                              >> do something like $new_class = new $class_name_str ing;
                              >>
                              >> I'd also like to thank you guys for all the help
                              >>[/color]
                              >
                              > The only problem might be - I don't know if you can do it directly. You
                              > may have to do something like
                              >
                              > $myObject = eval(new $className);
                              >
                              > Never tried it either way, though.
                              >[/color]
                              This seems to work as expected:

                              <?php
                              class A {
                              function ident() {
                              echo "This is class A\n";
                              }
                              }

                              class B {
                              function ident() {
                              echo "This is class B\n";
                              }
                              }

                              $classes = array('A', 'B');
                              foreach( $classes as $class ) {
                              $obj = new $class();
                              $obj->ident();
                              }
                              ?>

                              -david-

                              Comment

                              Working...