Connecting Tech Pros Worldwide Forums | Help | Site Map

Problems with include and duplication function definitions

Wescotte
Guest
 
Posts: n/a
#1: Apr 14 '06
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\Accounting\test1.php:5) in C:\Inetpub\Accounting\test2.php
on line 6

Assumed should be
Test1Test2

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

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

$a = new file_format("test1.php");
$b = new file_format("test2.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
Guest
 
Posts: n/a
#2: Apr 14 '06

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\Accounting\test1.php:5) in C:\Inetpub\Accounting\test2.php
> 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.


Wescotte
Guest
 
Posts: n/a
#3: Apr 14 '06

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.

Jerry Stuckle
Guest
 
Posts: n/a
#4: Apr 14 '06

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@attglobal.net
==================
Wescotte
Guest
 
Posts: n/a
#5: Apr 14 '06

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.

Jerry Stuckle
Guest
 
Posts: n/a
#6: Apr 14 '06

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@attglobal.net
==================
Wescotte
Guest
 
Posts: n/a
#7: Apr 17 '06

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($connection, $query);

$done = false;

while (odbc_fetch_row($result) || $done) {
include odbc_result($result, "class_source");
$test_case = new odbc_result($result, "class_name"); // I can't
see this working but I haven't specifcally tested it yet
if ($test_case.Known_File_Format($fillename)) {
$test_case.Parse_file($filename);
$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.

Jerry Stuckle
Guest
 
Posts: n/a
#8: Apr 17 '06

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($connection, $query);
>
> $done = false;
>
> while (odbc_fetch_row($result) || $done) {
> include odbc_result($result, "class_source");
> $test_case = new odbc_result($result, "class_name"); // I can't
> see this working but I haven't specifcally tested it yet
> if ($test_case.Known_File_Format($fillename)) {
> $test_case.Parse_file($filename);
> $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($fileFormat) {
case "format1" :
$myObject = new MyClass1();
break;
case "format2":
$myObject = new MyClass2();
break;
// etc.
}
if (myObject) {
$myObject->doSomething($odbc_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@attglobal.net
==================
Wescotte
Guest
 
Posts: n/a
#9: Apr 17 '06

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_Remittance()

DHL.php
DHL_Detected_EDI_Type()
DHL_Parse_EDI_File()
DHL_Create_Remittance()

while (odbc_fetch_row($result) || $done) {
$function = odbc_result($result, "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_Type

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

David Haynes
Guest
 
Posts: n/a
#10: Apr 17 '06

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_Remittance()
>
> DHL.php
> DHL_Detected_EDI_Type()
> DHL_Parse_EDI_File()
> DHL_Create_Remittance()
>
> while (odbc_fetch_row($result) || $done) {
> $function = odbc_result($result, "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_Type
>
> 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($result, 'class_name');
if( $obj = new $class_name() ) {
// call whatever method you need
$obj->Detected_EDI_Type();
$obj->Parse_EDI_File();
$obj->Create_Remittance();
}
}

-david-

Jerry Stuckle
Guest
 
Posts: n/a
#11: Apr 17 '06

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_Remittance()
>
> DHL.php
> DHL_Detected_EDI_Type()
> DHL_Parse_EDI_File()
> DHL_Create_Remittance()
>
> while (odbc_fetch_row($result) || $done) {
> $function = odbc_result($result, "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_Type
>
> 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($fileformat) {
switch($fileFormat) {
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@attglobal.net
==================
Wescotte
Guest
 
Posts: n/a
#12: Apr 17 '06

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

Wescotte
Guest
 
Posts: n/a
#13: Apr 17 '06

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_string;

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

Jerry Stuckle
Guest
 
Posts: n/a
#14: Apr 17 '06

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_string;
>
> 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@attglobal.net
==================
David Haynes
Guest
 
Posts: n/a
#15: Apr 18 '06

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_string;
>>
>> 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-

Closed Thread