-->

Php, odbc & vfp

2020-02-10 11:00发布

问题:

I'm trying to connect a dbf database with php. I've tried several different ways, with no luck.

PHP: 5.3.8 File: C:\xampp\htdocs\work\vcabdoc.dbf

1rst way:

created data source dbvfp, driver C:\Windows\system32\vfpodbc.dll

used $odbc = odbc_connect ('dbvfp', '', '') or die('Could Not Connect to ODBC Database!');

Warning: odbc_connect() [function.odbc-connect]: SQL error: [Microsoft][ODBC Visual FoxPro Driver]File c:\xampp\htdocs\work\vcabdoc.dbf is not a database., SQL state S1000 in SQLConnect in C:\xampp\htdocs\WORK\odbc.php on line 5

2nd way:

include('\xampp\php\PEAR\adodb\adodb.inc.php');
include_once('\xampp\php\PEAR\adodb\adodb-pager.inc.php');
session_start();
$db = ADONewConnection('vfp');
$dsn="Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=C:\\xampp\\htdocs\\work\\vcabdoc.dbf;Exclusive=No;";
$db->Connect($dsn) or die('nope');
$db->SetFetchMode(ADODB_FETCH_ASSOC);
$query = "Select * from vcabdoc.dbf";
$rs = $db->Execute($query);
echo 'e';
while (!$rs->EOF) {
    print_r($rs->fields);
    $rs->MoveNext();


Notice: Trying to get property of non-object in C:\xampp\htdocs\WORK\testing.php on line 45
Notice: Trying to get property of non-object in C:\xampp\htdocs\WORK\testing.php on line 46
Fatal error: Call to a member function MoveNext() on a non-object in C:\xampp\htdocs\WORK\testing.php on line 47

3rd way:

$conn = new COM("ADODB.Connection");
$conn->Open('Provider=VFPOLEDB.1;Data Source="C:\\xampp\\htdocs\\work\\vcabdoc.dbf;";');
// SQL statement to build recordset.
$rs = $conn->Execute("SELECT * FROM vcabdoc");

echo "<p>List of couriers:</p><hr>";
// Display all the values in the records set
while (!$rs->EOF) { 
    $fv = $rs->Fields("Name");
    echo $fv->value."<br>\n";
    $rs->MoveNext();
} 
$rs->Close(); 

Fatal error: Uncaught exception 'com_exception' with message '<b>Source:</b> Microsoft OLE DB Provider for Visual FoxPro<br/><b>Description:</b> Invalid path or file name.' in C:\xampp\htdocs\WORK\testing.php:54 Stack trace: #0 C:\xampp\htdocs\WORK\testing.php(54): com->Open('Provider=VFPOLE...') #1 {main} thrown in C:\xampp\htdocs\WORK\testing.php on line 54

I this case, tried with and without double slashes (\).

Any help? Thanks in advance.

Regards,

Joao

回答1:

The data source you are setting is inclusive of the full name of the .DBF... Don't do that. The data source should just point to the physical directory WHERE the table is .... Then, when you issue a query to a table, it looks in the path for a .dbf by the name you are querying, finds it and returns that... Also, you don't need to explicitly include .dbf, such as

select * from YourTable.dbf

EDIT PER FEEDBACK

Your "connection" that is being opened has a data source. That is telling where it should find the data. When connecting to a VFP source, all you have to do is set the source to the physical path of the table. Notice I just stripped off the "VCABDOC.DBF" from the string parameter.

$conn->Open('Provider=VFPOLEDB.1;Data Source="C:\\xampp\\htdocs\\work;";');

NOW, you should be able to just query directly from the table that is located in the "c:\xampp\htdocs\work" folder.

$rs = $conn->Execute("SELECT * FROM vcabdoc");

Finally, lets say you have more than one .dbf table in your "c:\xampp\htdocs\work" folder. Say a simple customer / order entry system and you want to get all orders for a specific person. As long as both tables are in the same folder (ie: work), then you could do something like

    $rs = $conn->Execute(
"SELECT customer.*, orders.* 
   FROM customer 
      join orders on customer.ID = orders.customerID 
      order by orders.date");

Notice I'm not explicitly throwing into the query the full path PLUS table name. The connection knows where it will try to find the tables to complete the query. Also, your connection does NOT allow you to go relative path BACKWARDS (closer to C:), but DOES allow you to go relatively FORWARD. So, say you have a directory structure something like

c:\xampp\htdocs\work\
c:\xampp\htdocs\work\SubFolder1
c:\xampp\htdocs\work\SubFolder2

And you make your connection point to the "work" folder as in the original sample. You COULD query referencing the subfolders in your query. In this query, I'm using an "alias" after each table name reference so I don't have to explicitly type the Long table name where used in the rest of the query. It makes for easier readability.

("c" is alias to customers table)
("sft1" is alias to Sub-folder first table )
("sft2" is alias to Sub-folder second table )

select 
      c.*, 
      sft1.someField, 
      sft2.AnotherField
   from 
      customers c
         join SubFolder1\SomeOtherTable sft1
            on c.SomeCommonColumn = sft1.SameCommonColumn
         join SubFolder2\SecondTable sft2
            on c.ADifferentColumn  =sft2.SimilarPurposeColumn

Hope this helps clarify some things for you.