Connecting to a MySQL database using DBI - mysql

I am trying to connect to a MySQL database.
I found this script and I am trying to use it on my PC and web host, but it doesn't show any output.
Please have a look at this code. I am running perl at xampp.
#!C:\xampp\perl\bin\perl.exe
print "Content-type: text/html\n\n";
use DBI;
use strict;
my $driver = "localhost";
my $database = "data";
my $dsn = "DBI:$driver:database = $database";
my $userid = "root";
my $password = "";
my $dbh = DBI->connect($dsn, $userid, $password ) or die $DBI::errstr;
I am using the same database with PHP.

but it doesn't show any output.
Judging by the CGI header you're displaying, I assume that you're running this as a CGI program. In which case, it's no surprised that you're not seeing any output - you're not sending any output.
If you ran it as a command line program (and it's often a good idea to get stuff working on the command line before leaping into CGI programming), then you would see the "Content-Type" header. Alternatively, you could add some output to your program and see if that appears in your browser. Something simple like:
print 'It works!';
I'd also like to add, that CGI looks rather outdated these days and there are far better (by which I mean easier and more powerful) ways to write web applications with Perl. You might like to read CGI::Alternatives to get an idea of what is available.
Update:
I've just seen this question asked on Facebook (please don't cross-post without telling people) and I've noticed that your $driver variable is wrong. If you're connecting to MySQL, then $driver should be "mysql" (so that DBI loads "DBD::mysql").

A DSN for the MySQL driver looks like this
DBI:mysql:database=$database;host=$hostname;port=$port
where the host and port fields are optional. (The database is also optional, but you don't want to leave that out.) There are several more esoteric options too, but they're irrelevant here
But you're supplying
DBI:localhost:database = data
Which doesn't even specify a MySQL connection, so I'm not surprised if it doesn't work! I don't know whether the spaces are legal, but I would leave them out to keep in line with the documentation.
You should change that statement to
my $dsn = "DBI:mysql:database=$database;host=$driver"
You may remove ;host=$driver if you wish (why have you called the host name "driver"?) as localhost is the default. A DSN that specifies just a database name and uses the default for all the other fields may be contracted to just
my $dsn = "DBI:mysql:$database"
It may be easier to just write print statements at first to generate some output. You will want to print a MIME content type header of text/plain instead of text/html. Try print "$DBI::errstr\n" for now instead of die, as the latter writes to stderr which won't appear in your browser

you could add:
if ($dbh) {
print 'connect ok';
} else {
print 'connect failed';
}

Related

Warning: mysql_num_rows() But only on webhost, not localhost

On localhost this works great. But when I upload files to server I get this error:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /storage/content/04/13fd39104/xxxxx.com/public_html/users/list.php on line 54
My code is:
//load users from database
$users = mysql_query("SELECT id,username FROM ".$sql_table_users." WHERE id!='".$_SESSION['user_id']."'");
if(mysql_num_rows($users) > 0){
while($user = mysql_fetch_assoc($users)){
//ALT tag contains user ID and user name
print '• '.$user['username'].'<br />';
}
}
Are you sure to have the same db strutture on server? Probably some column or table name are different from localhost. Check also if your db connection credentials are correct
Perhaps your database on server is not the same as your localhost.
add echo mysql_error(); after mysql_query to see details.
I would echo the query string before performing the query to see if it really is the string you think it should be. Most likely one of the variables is not defined so the query is failing. If that doesn't help you could also output any mysql errors after the query.
And of course, the obligatory suggestion to get off of the deprecated mysql_* functions! If you don't want to do PDO, check out mysqli and how very similar it is to the mysql functions if you use the procedural functions.

MYSQLI not playing nice with INSERT

So excuse the coding if it's not totally up to par, but I just got a hang of MYSQL and am switching to MYSQLI (procedural as I find it easier as I haven't learned object oriented yet, i'm new to this)
My problem is I have a simple 'Invoice' page on a small website that worked perfectly with MYSQL. When I switched to MYSQLI (I'm sure I am missing something obvious) I can echo all the variables, have checked for proper DB connection yet it will not INSERT anything into the DB.
This is the function in question, it is called after a "fill invoice" form is submitted, again, all the $_POST variables can be echoed in the function properly.
function createinvoice($billto,$cust,$addr,$desc,$desccost,$labcost,$comment){
$taxrate=".13";
$kaboom=str_replace(array("\r\n","\r","\n"),"<br />",$desccost); //keep original desccost for database
$kaboom=mysqli_real_escape_string(nl2br($kaboom));
$kaboom=nl2br($kaboom);
$lines=explode("<br />",$kaboom);
$matcost=0;
for($i=0;$i < count($lines);$i++)
{
$matcost=$matcost+$lines[$i];
}
$fullcost=$matcost+$labcost;
$taxdue = $fullcost*$taxrate;
$totaldue=$fullcost+$taxdue;
$desc=mysqli_real_escape_string($desc);
mysqli_query($con,"INSERT INTO invoice(customerID,customerName,customerAddr,description,desccost,material,labour,taxdue,totaldue,comment)
VALUES('$billto','$cust','$addr','$desc','$desccost','$matcost','$labcost','$taxdue','$totaldue','$comment')");
mysqli_free_result($result);
mysqli_close($con);
}
Edit: to show connection string
if(include("/../dbinvoice.php")){echo "DB file connected";}
$con = mysqli_connect($dbhostname, $dbuser, $dbpass, $dbname);
if (mysqli_connect_errno($con)){echo "No MYSQL connection: ".mysqli_connect_error();exit();}
Every time the page loads I get a message "DB file connected" showing it read the dbinvoice.php file and I don't get an error message with connect. I have verified with phpinfo() that mysqli is on my machine (webmatrix testing).

Why does my Perl script fail to connect to the database?

I have a Perl script which retrieves data from MySQL Database. this is the code:
sub startSession{
my $self = shift;
my $dsn = "dbi:".$self{platform}.":".$self{database}.":".$self{host}.":".$self{port};
print "$dsn\n" ;
$self{dbHandle} = DBI->connect($dsn,$user,$password);
}
I have provided every information from an external file. I get the error message
DBI connect('dbname:**.**.**.**:3306','',...) failed: Access denied for user 'root'#'dbserver' (using password: NO) at line 89
Can't call method "prepare" on an undefined value at at line 97
I am very sure the root can connect from any host and the password is also correct.
First, your immediate problem, is as #Sinan Ünür says, that you need to change $self{platform} to $self->{platform}, etc.
Your second immediate problem is that it appears you're getting $user and $password from nowhere (they are not passed to the function, so they are undefined unless they are global variables), which would explain the using password: NO part of the error. Maybe those should be $self->{user} and $self->{password}?
You should considering put this at the top of your module, at least during development, to automatically catch errors like these:
use warnings qw(all);
use strict;
But I'd also comment, that from a design perspective, you really ought to treat DSNs as opaque strings. Each database has its own DSN format. So if you ever want to target a different database, you'll need a different DSN format. Or, possibly, someday MySQL will use a different format (it already has two). Either way, it'll be much easier to change it one place, in a configuration file, than to track down each place you concatenate the various pieces together.
The key part of the warning that I see is "using password: NO". Check that the password is being set properly.
Presumably, $self is a hashref, not a plain hash, and you don't have warnings on. So, turn them on, and use $self->{platform} etc.

MySQL credentials/hosts variables best practices

I want to know what is the best practice or what is recommended to do when a variables are created for MySQL credentials/host.
define('HOST', 'localhost');
// etc..
mysql_connect(HOST, // etc...
vs
$host = 'localhost';
// etc..
mysql_connect($host, // etc...
For both you can easily check what are the declared variables or constants and maybe can find what are the value easily. I have code that multiple users can share and use.
What is the best way to protect these variables?
Here's few solutions
1) You give each user a user and password and each user has their permissions in the database (only select, or insert ect..). So in your code you simply include a db.config.php so all the variables are set. It does not really matter if the user echo the variables since they use their own.
2) you can give a common username/pass for the database and then encode the file (either using custom encoding, zend optimizer or ioncube and unset the variables. Here's a sample code:
// file mysql_connect.php
$link = mysql_connect("localhost", "mysql_user", "mysql_password")
or die("cannot connect to database : " . mysql_error());
// then this file is encoded so nobody can view it.
3) At some point, someone, somehow will be able to find this information. I would simply recommend to trust your user (assuming these are developers)
At some point in your code you will have to hardcode this kind of information, the important thing is to keep it in only one place to promote maintanability.
However, as you are worried about security I suggest you to check this: Convert PHP file to binary

Perl DBI MySQL Error Msg : Can't call method "do" on an undefined value

I am trying to run simple perl dbi example script to connect to mysql database and do some inserts.
Code:
#! bin/usr/perl -w
use strict;
use warnings;
use DBI();
my $dbh = DBI->connect(
"DBI:mysql:database=SPM;host=IP Address", "username", "password",
{'RaiseError'=>1}
);
my $dbh->do(
'INSERT INTO payment_methods(name, description)VALUES(CASH, DOLLAR)'
);
my $dbh->disconnect();
But when I try to run this using perl filename.pl I get following
Can't call method "do" on an undefined value at perldbi.pl line 12
That is where I have used do for first time.
I have tried to google it and also to tried all different kinds of forum but in vain, if you have any idea as to why this is happening and what is way around for this than it would be really great and I would really appreciate your help.
You have an extra my:
my $dbh->do(
'INSERT INTO payment_methods(name, description)VALUES(CASH, DOLLAR)'
);
Get rid of that my.
You either do not really have warnings enabled in your script or you are ignoring the warnings:
#!/usr/bin/perl
use strict;
use warnings;
my $x = 1;
my $x = 2;
C:\Temp> t
"my" variable $x masks earlier declaration in same scope at ...
I doubt it's the reason for the error message, but the values in the insert are probably not right:
VALUES(CASH, DOLLAR)
Should probably be:
VALUES(\'CASH\', \'DOLLAR\')
The \ is required because you're using a ' style string. If you use a " style string instead, you could leave out the \:
"... VALUES('CASH','DOLLAR')"
As daotoad said, your DBI->connect call is failing. Check your connection settings, see if you can connect to the database from the command line, etc. In your Perl script, always check the return value of DBI->connect() to see if the connection was successful.
my $dbh = DBI->connect("DBI:mysql:database=SPM;host=IP Address",...)
or die sprintf( 'connect() failed. Error: %s', DBI->errstr);
my $dbh->do(q{
INSERT INTO payment_methods(name, description)VALUES(CASH, DOLLAR)
});
...
Your database connection is failing. So $dbh is undefined.
Update: Both comments are right. Sinan has the correct answer--the OP is using my on every line.