how to change mysql_query to mysqli_guery - mysqli

I am using in a script mysqli_query but i think there is something wrong with the syntaxes. The script did work before, but changing everything form mysql_query to mysqli_query, data is not put anymore correct in the database.
This was the original query:
mysql_query( "INSERT INTO download_manager (SET filename='".mysqli_real_escape_string($_GET['file'])."'),
ON DUPLICATE KEY UPDATE downloads=downloads+1");
I changed it with mysqli_query this way:
mysqli_query($link, "INSERT INTO download_manager (SET filename='".mysqli_real_escape_string($_GET['file'])."'),
ON DUPLICATE KEY UPDATE downloads=downloads+1");
Can someone tell me what i did wrong?
Update:
My connection looks like this:
$link = #mysqli_connect($db_host, $db_user, $db_pass, $db_database) or die ("Error " . mysqli_error($link));
mysql_set_charset('utf8');

Ensure that the handle stored in $link was generated from a call to mysqli_connect and not mysql_connect:
http://php.net/manual/en/function.mysqli-connect.php
If that fails, check for an error:
die(mysqli_error($link))
Troubleshooting
The mysql and mysqli PHP modules are distinct, and you can't mix functions between the modules.
Enable error reporting to ensure you are able to see useful error messages.
Ensure the database credentials and connection details are valid.
Use mysqli_error after mysqli_xxx function calls to detect issues within the mysqli module.
Use the # token sparingly to avoid hiding useful errors.

Related

mysqli_query($conn, $sql) On adding this, giving an error of 500 INTERNAL SERVER ERROR, No detailed error shown [duplicate]

In my local/development environment, the MySQLi query is performing OK. However, when I upload it on my web host environment, I get this error:
Fatal error: Call to a member function bind_param() on a non-object in...
Here is the code:
global $mysqli;
$stmt = $mysqli->prepare("SELECT id, description FROM tbl_page_answer_category WHERE cur_own_id = ?");
$stmt->bind_param('i', $cur_id);
$stmt->execute();
$stmt->bind_result($uid, $desc);
To check my query, I tried to execute the query via control panel phpMyAdmin and the result is OK.
TL;DR
Always have mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); in your mysqli connection code and always check the PHP errors.
Always replace every PHP variable in the SQL query with a question mark, and execute the query using prepared statement. It will help to avoid syntax errors of all sorts.
Explanation
Sometimes your MySQLi code produces an error like mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, boolean given..., Call to a member function bind_param()... or similar. Or even without any error, but the query doesn't work all the same. It means that your query failed to execute.
Every time a query fails, MySQL has an error message that explains the reason. In the older PHP versions such errors weren't transferred to PHP, and all you'd get is a cryptic error message mentioned above. Hence it is very important to configure PHP and MySQLi to report MySQL errors to you. And once you get the error message, fixing it will be a piece of cake.
How to get the error message in MySQLi
First of all, always have this line before MySQLi connect in all your environments:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
After that, all MySQL errors will be transferred into PHP exceptions. An uncaught exception, in turn, makes a PHP fatal error. Thus, in case of a MySQL error, you'll get a conventional PHP error. That will instantly make you aware of the error cause. And the stack trace will lead you to the exact spot where the error occurred.
How to get the error message from PHP
Here is a gist of my article on PHP error reporting:
Reporting errors on a development and live servers must be different. On the development server it is convenient to have errors shown on-screen, but on a live server error messages must be logged instead, so you could find them in the error log later.
Therefore, you must set corresponding configuration options to the following values:
On a development server
error_reporting should be set to E_ALL value;
log_errors should be set to 1 (it is convenient to have logs on a development PC too)
display_errors should be set to 1
On a production server
error_reporting should be set to E_ALL value;
log_errors should be set to 1
display_errors should be set to 0
After that, when MySQL query fails, you will get a PHP error that explains the reason. On a live server, in order to get the error message, you'll have to check the error log.
In case of AJAX call, on a dev server open DevTools (F12), then Network tab. Then initiate the request which result you want to see, and it will appear in the Network tab. Click on it and then the Response tab. There you will see the exact output. On a live server check the error log.
How to actually use it
Just remove any code that checks for the error manually, all those or die(), if ($result), try..catch and such. Simply write your database interaction code right away:
$stmt = $this->con->prepare("INSERT INTO table(name, quantity) VALUES (?,?)");
$stmt->bind_param("si", $name, $quantity);
$stmt->execute();
Again, without any conditions around. If an error occurs, it will be treated like any other error in your code. For example, on a development PC it will just appear on-screen, while on a live site it will be logged for the programmer, whereas for the user's convenience you could use an error handler (but that's a different story which is off topic for MySQLi, but you may read about it in the article linked above).
What to do with the error message you get
First of all you have to locate the problem query. The error message contains the file name and the line number of the exact spot where the error occurred. For the simple code that's enough, but if your code is using functions or classes you may need to follow the stack trace to locate the problem query.
After getting the error message, you have to read and comprehend it. It sounds too obvious if not condescending, but learners often overlook the fact that the error message is not just an alarm signal, but it actually contains a detailed explanation of the problem. And all you need is to read the error message and fix the issue.
Say, if it says that a particular table doesn't exist, you have to check spelling, typos, and letter case. Also you have to make sure that your PHP script connects to a correct database
Or, if it says there is an error in the SQL syntax, then you have to examine your SQL. And the problem spot is right before the query part cited in the error message.
If you don't understand the error message, try to google it. And when browsing the results, stick to answers that explain the error rather than bluntly give the solution. A solution may not work in your particular case, but the explanation will help you to understand the problem and make you able to fix the issue by yourself.
You have to also trust the error message. If it says that number of tokens doesn't match the number of bound variables then it is so. The same goes for the absent tables or columns. Given the choice, whether it's your own mistake or the error message is wrong, always stick to the former. Again it sounds condescending, but hundreds of questions on this very site prove this advise extremely useful.
A list of things you should never ever do in regard of error reporting
Never use an error suppression operator (#)! It makes a programmer unable read the error message and therefore unable to fix the error
Do not use die() or echo or any other function to print the error message on the screen unconditionally. PHP can report errors by itself and do it the right way depends on the environment - so just leave it for PHP.
Do not add a condition to test the query result manually (like if($result)). With error exceptions enabled such condition will just be useless.
Do not use the try..catch operator for echoing the error message. This operator should be used to perform some error handling, like a transaction rollback. But never use it just to report errors - as we learned above, PHP can already do it, the right way.
P.S.
Sometimes there is no error, but no results either. Then it means, there is no data in the database to match your criteria. In this case you have to admit this fact, even if you can swear the data and the criteria are all right. They are not. You have to check them again.
I've got an article that can help in this matter, How to debug database interactions. Although it is written for PDO, the principle is the same. Just follow those instructions step by step and either have your problem solved or have an answerable question for Stack Overflow.

setCredentialTreatment is not available in SQLite

I ran into a strange error, I want to share it with you.
I had to convert my MySQL database to SQLite, which was actually a piece of cake with the program called DBConvert.
So I changed in my application.ini:
resources.db.adapter = "PDO_SQLITE"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/db_name.db"
And try to show my website, everything looks correct. Except when I try to login to my website, it gives the following error:
The supplied parameters to Zend_Auth_Adapter_DbTable failed to produce a valid sql statement, please check table and column names for validity.
setCredentialTreatment(SHA(?)) is not supported by SQLite.
Remove that setCredentialTreatment line, and change the following:
$authAdapter->setCredential(**sha1(**$password));

Using db:populate causing nil exception

I'm using db:populate to preload some sample data into my rails project. For instance, I am using the following code to populate the db:
require 'faker'
namespace :db do
task :populate => :environment do
Rake::Task['db:reset'].invoke
100.times do |u|
User.create!(
:name => Faker::Name.name,
:email => Faker::Internet.email
)
end
puts "The count of user(s) is #{User.all.count}"
User.all.each do |u|
# Add some more info based for each user
end
end
end
However, what I get is an error when I run "rake db:populate". I get:
rake aborted!
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
I get this error on the call to puts where I print out the count of users.
If I reduce the 100.times down to about 10.times, the populate works correctly and the call to User.all.count responds with the correct value of 10.
The best that I can guess is that the call to "faker" gets overloaded and has not yet returned a value which causes the nil object. Maybe however, the populate is trying to run this as a single database transaction and is overloading some buffer.
Is there a way to "flush" the insert into the database so that each transaction is written to the database or pause while "faker" responds so I can create a larger data set to work with?
Thanks
Steve Woolley
swoolley#ardentsoft.com
I had the same problem
just running rake db:seed on a few console type expressions,
after doing a trace it says:
** Invoke environment (first_time)
** Execute environment
Now I don't have an environment 'first_time'
I looked at what I changed and it turns out I was calling by default a different environment in the initializer when attempting to connect to the db.
Take a look at your database.yml or application.rb files there might be a conflict
Cheers

How do I get the text-form verification code when doing auto site access in Perl?

I'm playing around with Win32::IE:Mechanize to try to access some authentication-required sites automatically. So far I've achieved moderate success, for example, I can automatically log in to my yahoo mailbox. But I find many sites are using some kind of image verification mechanism, which is possibly called CAPTCHA. I can do nothing to them. But one of the sites I'm trying to auto access is using a plain-text verification code. It is comnposed of four digits, selectable and copyable. But they're not in the source file which can be fetched using
$mech->content;
I searched for the keyword that appears on the webpage but not in the source file through all the files in the Temporary Internet Files but still can't find it.
Any idea what's going on? I was suspecting that the verification code was somehow hidden in some cookie file but I can't seem to find it :(
The following is the code that completes all the fields requirements except for the verification code:
use warnings;
use Win32::IE::Mechanize;
my $url = "http://www.zjsmap.com/smap/smap_login.jsp";
my $eccode = "myeccode";
my $username = "myaccountname";
my $password = "mypassword";
my $verify = "I can't figure out how to let the script get the code yet"
my $mech = Win32::IE::Mechanize->new(visible=>1);
$mech->get($url);
sleep(1); #avoids undefined value error
$mech->form_name("BaseForm");
$mech->field(ECCODE => $eccode);
$mech->field(MEMBERACCOUNT => $username);
$mech->field(PASSWORD => $password);
$mech->field(verify => $verify);
$mech->click();
Like always any suggestions/comments would be greatly appreciated :)
UPDATE
I've figured out a not-so-smart way to solve this problem. Please comment on my own asnwer posted below. Thanks like always :)
This is the reason why they are there. To stop program like yours to do automated stuff ;-)
A CAPTCHA or Captcha is a type of
challenge-response test used in
computing to ensure that the response
is not generated by a computer.
This appears to be an irrelevant number. The page uses it in 3 places: generating it; displaying it on the form next to the input field for it; and checking for the input value being equal to the random number chosen. That is, it is a client-only check. Still, if you disable javascript it looks like, I'm guessing, important cookies don't get set. If you can execute JavaScript in the context of the page (you should be able to with a get method call and a javascript URI), you could change the value of random_number to f.e. 42 and fill that in on the form.
The code is inserted by JavaScript – disable JS, reload the page and see it disappear. You have to hunt through the JS code to get an idea where it comes from and how to replicate it.
Thanks to james2vegas, zoul and Shoban.
I've finally figured out on my own a not-so-smart but at-least-workable way to solve the problem I described here. I'd like to share it here. I think the approach suggested by #james2vegas is probably much better...but anyway I'm learning along the way.
My approach is this:
Although the verification code is not in the source file but since it is still selectable and copyable, I can let my script copy everything in the login page and then extract the verification code.
To do this, I use the sendkeys functions in the Win32::Guitest module to do "Select All" and "Copy" to the login page.
Then I use Win32:Clipboard to get the clipboard content and then Regexp to extract the code. Something like this:
$verify = Win32::Clipboard::GetText();
$verify =~ s/.* (\d{4}).*/$1/msg;
A few thoughts:
The random number is generated by something like this in Perl
my $random_number = int(rand(8999)) + 1000; #var random_number = rand(1000,10000);
And then it checks if $verify == $random_number. I don't know how to catch the value of one-session-only $random_number. I think it is stored somewhere in the memory. If I can capture the value directly then I wouldn't have gone to so much trouble of using this and that extra module.

Perl -Database-Connection Count/error handling

Using a perl script (Perl 5.8.6), I'm connecting to Sybase dataserver.
Looking for the following:
How many connections are currently opened by the script.
Generic (non-dataserver specific) Error handling modules/mechanism
When executing a stored proc, it returned the following error message.
DBD::Sybase::st execute failed: Server
message number=27000 severity=16
state=1 line=4 server=SYBDEV_HYD
procedure=j_err text=But this one does
[for Statement "EXEC sandbox..j_err"]
at
/usr/local/lib/perl5/site_perl/5.8.6/DBIx/ContextualFetch.pm
line 51.
Since the user of this script is a non-techie, trying to report only the message "But this one does" (that appears after the text=). Though I can parse this, trying to see if there is any generic module, since other dataserver (like MySQL, SQL Server etc.) can have their own way of reporting the error msg.
I'm not quite sure what you're asking, but you'll find a lot of information by reading through the documentation for DBD::Sybase and DBI. You probably have to keep track of the number of connections yourself (see the example for DBI->connect).
For error-handling, you should probably just compose a reasonable diagnostic message yourself along with a line number - you can do this easily with warn() or carp().
Please also feel free to edit your question with more specifics about what you are trying to do; some sample code would be helpful.