PHP ODBC - Access 2007: Function Call Problems: odbc_columns - php

I have mananed to use the odbc_connect like the following for access 2007 and 2003 and I can get data. But when I try to get the column names the following function will not work for access 2007 but will for acccess 2003 - why?
if($type[1]=='mdb'){
$connection = odbc_connect("Driver={Microsoft Access Driver (*.mdb)};Dbq=$mdbFilename", $username, $password);
}else{
$connection = odbc_connect("Driver={Microsoft Access Driver (*.accdb)};Dbq=$mdbFilename", $username, $password);
}
function get_columns($activity_file){
global $connection;
global $typee;
$coulmn_array = array();
$result = odbc_columns($connection, $typee, "", $activity_file, "%");
while (odbc_fetch_row($result)) {
$coulmn_array[] = odbc_result($result, "COLUMN_NAME");
}
echo '<br>Exporting table '.$activity_file;
return $coulmn_array;
}
I mean I can get the data and everything, it just seems this function just won't work!
Please help!
Update
I had a google around and found this thread.
I can confirm what this person is saying. Supplying a table_name means this won't work. But if you don't it will. This isn't acceptable as what columns are being returned and for what table? I need to know this!!

This is a long shot, but there was a problem with the ODBC function SQLDescribeCol and SQLColAttributes related to Access 2007. Those functions would likely be used by odbc_columns. It is described in this KB article.

Related

Library List is not being used in remote PHP DB2 connection to IBM i

I've successfully connected to a remote IBM i DB2 database (AS400) from my local Windows PC via PHP. I'm using the IBM Data Server Client in conjunction with the db2_* functions in PHP. The problem I'm having is that despite my library list being set properly, it is not being used for unqualified table names. Instead it uses the current user name as the library. However, when I qualify the table names everything works like a charm.
I've confirmed that my library list is actually changing when I create the connection by querying QSYS2.LIBRARY_LIST_INFO.
$database = '<database name>';
$user = '<user name>';
$password = '<password';
$port = <port>;
$options['i5_naming'] = DB2_I5_NAMING_ON;
$options['autocommit'] = DB2_AUTOCOMMIT_OFF;
$options['i5_libl'] = 'MYLIB YOURLIB ANYLIB';
$conn = db2_connect($database, $user, $password, $options);
if ($conn) {
echo "Connection succeeded."; //It succeeds
}
else {
echo db2_conn_error()." | ".db2_conn_errormsg()."<br />";
echo "Connection failed.";
}
$sql = "SELECT * FROM QSYS2.LIBRARY_LIST_INFO";
//Works and proves my library list reflects
//what I passed in when creating the connection.
//$sql = "SELECT * FROM LIBRARY_LIST_INFO";
//Generates: "42S02 : [IBM][CLI Driver][AS] SQL0204N "<user name>.LIBRARY_LIST_INFO" is an undefined name. SQLSTATE=42704 SQLCODE=-204"
//where <user name> is the username used to connect to the DB.
//It should be using the library list specified when creating the connection though.
//This holds true for any table from any library including those specified
//when creating the connection (which includes QSYS2).
$stmt = db2_prepare($conn, $sql);
$result = db2_execute($stmt);
if($result){
while($row = db2_fetch_assoc($stmt)){
echo "<pre>";
var_dump($row); //In addition to entries for QSYS, QSYS2, QUSRSYS and QHLPSYS I get entries for MYLIB, YOURLIB and ANYLIB.
echo "</pre>";
}
}else{
echo "failed<br />";
echo db2_stmt_error()." : ".db2_stmt_errormsg()."<br />";
}
Has anyone ever run into this while enabling i5_naming when connecting to a remote DB2 server? I'm not really sure why it wouldn't be using my library list as the PHP manual states "Unqualified files are resolved using the library list for the job." when enabled. http://php.net/manual/en/function.db2-connect.php
I finally solved this after opening a PMR with IBM. All I had to do was apply the latest Fix Pack for DB2 Connect Personal Edition.
Suggested Fix Packs for DB2 Connect:
http://www-01.ibm.com/support/docview.wss?rs=71&uid=swg21321001
Basically the DB2 Connect version I had was released prior to 2013. It was in 2013 IBM added two tier support by adding the i5_naming option. So my DB2 Connect setup was effectively ignoring the option I was passing. So that explains why the other options still went through. On the DB side, since it didn't receive a value for i5_naming - it remained as the default.

Grabbing things from database using functions. Is this safe?

I have a simple question. I'm not too good at programming yet but is this safe and correct?
Currently I am using functions to grab the username, avatars, etc.
Looks like this:
try {
$conn = new PDO("mysql:host=". $mysql_host .";dbname=" . $mysql_db ."", $mysql_username, $mysql_password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
config.php ^^
function getUsername($userid) {
require "config/config.php";
$stmt = $conn->prepare("SELECT username FROM accounts WHERE id = ? LIMIT 1");
$stmt->execute([$userid]);
$name = $stmt->fetch();
return $name["username"];
}
function getProfilePicture($userid) {
require "config/config.php";
$stmt = $conn->prepare("SELECT profilepicture FROM accounts WHERE id = ? LIMIT 1");
$stmt->execute([$userid]);
$image = $stmt->fetch();
return $image["profilepicture"];
}
Is this correct and even more important, is this safe?
Yes, it's safe with respect to SQL injections.
Some other answers are getting off topic into XSS protection, but the code you show doesn't echo anything, it just fetches from the database and returns values from functions. I recommend against pre-escaping values as you return them from functions, because it's not certain that you'll be calling that function with the intention of echoing the result to an HTML response.
It's unnecessary to use is_int() because MySQL will automatically cast to an integer when you use a parameter in a numeric context. A non-numeric string is interpreted as zero. In other words, the following predicates give the same results.
WHERE id = 0
WHERE id = '0'
WHERE id = 'banana'
I recommend against connecting to the database in every function. MySQL's connection code is fairly quick (especially compared to some other RDBMS), but it's still wasteful to make a new connection for every SQL query. Instead, connect to the database once and pass the connection to the function.
When you connect to your database, you catch the exception and echo an error, but then your code is allowed to continue as if the connection succeeded. Instead, you should make your script die if there's a problem. Also, don't output the system error message to users, since they can't do anything with that information and it might reveal too much about your code. Log the error for your own troubleshooting, but output something more general.
You may also consider defining a function for your connection, and a class for your user. Here's an example, although I have not tested it:
function dbConnect() {
try {
$conn = new PDO("mysql:host=". $mysql_host .";dbname=" . $mysql_db ."", $mysql_username, $mysql_password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e)
{
error_log("PDO connection failed: " . $e->getMessage());
die("Application failure, please contact administrator");
}
}
class User {
protected $row;
public function __construct($userid) {
global $conn;
if (!isset($conn)) {
$conn = dbConnect();
}
$stmt = $conn->prepare("SELECT username, profilepicture FROM accounts WHERE id = ? LIMIT 1");
$stmt->execute([$userid]);
$this->row = $stmt->fetch(PDO::FETCH_ASSOC);
}
function getUsername() {
return $this->row["username"]
}
function getProfilePicture() {
return $this->row["profilepicture"]
}
}
Usage:
$user = new User(123);
$username = $user->getUsername();
$profilePicture = $user->getProfilePicture();
That looks like it would work assuming that your config file is correct. Because it is a prepared statement it looks fine as far as security.
They are only passing in the id. One thing you could do to add some security is ensure that the $userid that is passed in is the proper type. (I am assuming an int).
For example if you are expecting an integer ID coming in and you get a string that might be phishy (possible SQL injection), but if you can confirm that it is an int (perhaps throw an error if it isn't) then you can be sure you are getting what you want.
You can use:
is_int($userid);
To ensure it is an int
More details for is_int() at http://php.net/manual/en/function.is-int.php
Hope this helps.
It is safe (at least this part of the code, I have no idea about the database connection part as pointed out by #icecub), but some things you should pay attention to are:
You only need to require your config.php once on the start of the file
You only need to prepare the statement once then call it on the function, preparing it every time might slow down your script:
The query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters. When the query is prepared, the database will analyze, compile and optimize its plan for executing the query. - PHP Docs
(Not an error but I personally recommend it) Use Object Orientation to help organize your code better and make easier to mantain/understand
As stated by #BHinkson, you could use is_int to validate the ID of the user (if you are using the IDs as numbers)
Regarding HTML escaping, I'd recommend that you already register your username and etc. HTML escaped.

Mongo db connectivity Error?

<?php
$username='root';
$password='xyz';
$database='abc';
$host='localhost';
function MongoConnect($username, $password, $database, $host) {
$con = new Mongo("mongodb://{$username}:{$password}#{$host}"); // Connect to Mongo Server
$db = $con->selectDB($database); // Connect to Database
}
$collection=$db->movie;
$document = array( "name" =>"Calvin and Hobbes");
$collection->insert($document);
// find everything in the collection
$cursor = $collection->find();
// iterate through the results
foreach ($cursor as $document) {
echo $document["name"] . "\n";
}
?>
I had installed MONGO DB and tried to test my DB, but I am getting an ERROR
"Internal Server Error 500"
And also my Test.php file have my own content called Hello World, but if I had run the TEST.php file it displays Nothing.
My DB table is not accessing and I wasn't able to retrieve data from my Database.
So Kindly help me out here.
There can be several things wrong.
First - is Mongo driver installed?
Second - your MongoConnect function have no effect. You are defining it and not calling. Plus even if you would call it there would be no effect as $db is only in function scope and not outside.
Third - because function MongoConnect have no effect "$collection=$db->movie;" will result in problem as $db is not defined.
Consult http://php.net/manual/en/mongocollection.insert.php on how to insert data in collection.
Internal Server Error only occured when misspelled in code or some of function called wrongly. Please review ur code.

PHP call to SQL server stored procedure doesn't work when ported from Windows to Linux

This is pretty similar to this question, but I need to capture output. It seems to be basically an issue with getting the correct syntax, but using the syntax suggested in the answer didn't work for me.
I have a php application that calls a stored procedure on a SQL Server database which I developed on my Windows laptop running xampp.
My stored procedure looks like this:
CREATE Procedure [dbo].[check_for_barcode] #Sample_Id nvarchar(20), #Barcode_In_table int OUTPUT
AS
SELECT #Barcode_In_table = count(*) FROM dbo.sample_info
WHERE sample_name = #Sample_Id
RETURN #Barcode_In_table
GO
The php code that works on Windows xampp looks like this:
// use a sample Id known to be present in database
$sample_yes = '11335577';
// use a sample Id known NOT to be in database
$sample_no = '0011223344';
$host = 'hostIP';
$db = 'db';
$user = 'user';
$password = 'pw';
try {
$conn = new PDO("sqlsrv:Server=$host;Database=$db", $user, $password);
$sql = "{CALL dbo.check_for_barcode(#Sample_Id=:barcode, #Barcode_In_table=:isInDatabase)}";
$stmt = $conn->prepare($sql);
$stmt-> bindParam('barcode', $sample_yes, PDO::PARAM_STR);
$stmt->bindParam('isInDatabase', $isInDatabase, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 4);
$stmt->execute();
echo 'for sample id 11335577 $isInDatabase = '.$isInDatabase."\n";
$stmt-> bindParam(':barcode', $sample_no);
$stmt->execute();
echo 'for sample id 0011223344 $isInDatabase = '.$isInDatabase;
$stmt->closeCursor();
}
catch (Exception $e) {
echo $e->getMessage();
}
The output is:
for sample id 11335577 $isInDatabase = 1
for sample id 0011223344 $isInDatabase = 0
Since moving it to the Linux (Ubuntu 4.24) server where it will be deployed, it no longer works.
I installed the dblib drivers as described here.
I adapted the code to as required to use the dblib driver so that it would run without errors. This only involved changing the first two lines inside the try statement.
I have changed the first line to:
...
$conn = new PDO("dblib:host=$host;dbname=$db", $user, $password);
...
I have tried all of the following for the second line:
$sql = "{CALL dbo.check_for_barcode(#Sample_Id=:barcode, #Barcode_In_table=:isInDatabase)}";
$sql = "{CALL dbo.check_for_barcode #Sample_Id=:barcode, #Barcode_In_table=:isInDatabase}";
$sql = "CALL dbo.check_for_barcode(#Sample_Id=:barcode, #Barcode_In_table=:isInDatabase)";
$sql = "CALL dbo.check_for_barcode :barcode, :isInDatabase";
As well as all of the above using EXEC instead of CALL
The output in all cases is:
for sample id 11335577 $isInDatabase =
for sample id 0011223344 $isInDatabase =
If I add ...
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
var_dump($result);
}
... this generates no output.
There are no error message at all, so I can't see where the problem is. I would welcome any suggestions on what to try next.
It's been a while since I had to do this, but I used ODBC to connect to SQL Server from PHP running on a linux box.
Drivers - http://msdn.microsoft.com/en-gb/data/ff657782.aspx
ODBC docs - http://www.php.net/manual/en/ref.pdo-odbc.connection.php
EDIT: The ODBC drivers above are for Windows, the Linux installation instructions and drivers can be found at www.php.net/pdo_odbc

PHP Fatal error: Call to undefined method mysqli::mysqli_fetch_all()

hoping someone can help me, I am having the following error, looked online and tried a load of things but can't seem to figure it out, error:
Fatal error: Call to undefined method mysqli::mysqli_fetch_all() in C:\xampp\htdocs\cyberglide\core-class.php on line 38
heres my code:
<?php
class Core {
function db_connect() {
global $db_username;
global $db_password;
global $db_host;
global $db_database;
static $conn;
$conn = new mysqli($db_host, $db_username, $db_password, $db_database);
if ($conn->connect_error) {
return '<h1>'."Opps there seems to be a problem!".'</h1>'.'<p>'."Your Config file is not setup correctly.".'</p>';
}
return $conn;
}
function db_content() {
//this requires a get, update and delete sections, before its complete
$conn = $this->db_connect();
if(mysqli_connect_errno()){
echo mysqli_connect_error();
}
$query = "SELECT * FROM content";
// Escape Query
$query = $conn->real_escape_string($query);
// Execute Query
if($result = $conn->query($query)){
// Cycle through results
while($row = $conn->mysqli_fetch_all()){
//echo $row->column;
}
}
}
}
$core = new Core();
?>
I am trying to create a db_connect function, which I want to be able to call anywhere on the site that needs a database connection, I am trying to call that function on a function within the same class, I want it to grab and display the results from the database. I am running PHP 5.4.7, I am calling the database on a blank php file which includes a require to include the class file, then using this at the moment $core->db_content(); to test the function. I am building this application from scratch, running from MySQLi guides (not used MySQLi before, used to use normal MySQL query's) so if I am doing anything wrong please let me know, thanks everyone.
mysqli_fetch_all is a method of a mysqli_result, not mysqli.
So presumably it should be $result->fetch_all()
References:
http://php.net/manual/en/mysqli-result.fetch-all.php
Important: keep in mind mysqli_result::fetch_all returns the whole result set not a row as you assume in your code
There are three problems I see here.
while($row = $conn->mysqli_fetch_all()){
The method name is fetch_all() when used in the OOP way.
fetch_all() should be used with the $result object
fetch_all() is only available when the mysqlnd driver is installed - it frequently is not.
Reference
Only $result has that method. If you want to use it in a while loop use fetch_assoc(). fetch_all() returns an associative array with all the data already.
while($row = $result->fetch_assoc()){
}
thanks all, its working fine now, i had it as while($row = $conn->fetch_assoc()){
} before and changed to what i put above, but dident see it should of been $result instead of $conn, thanks for pointing that out.

Categories