Jump to content

Object of class mysqli_result could not be converted to int


Jonnyfencing1

Recommended Posts

I have a new project I'm working on where I am making an affiliate program and I am making a bit where if the same IP visits the link more thna 5 times it blocks it from adding on 1 click and I get this error whenever I try to test it out its on Line 17 I will paste my full PHP file below with line 17 in Bold and Underlined.

 
<?php
session_start();
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) { die('Invalid id'); }
 
$conn = mysqli_connect("redacted", "redacted", "redacted", "redacted");
if (!$conn) {
    die("Connection failed: ".mysqli_connect_error());
}
 
$ip = $_SERVER['REMOTE_ADDR'];
$sql = ("SELECT ip FROM ips WHERE ip='$ip'");
$qry = $conn->query($sql);
if ($qry = 0) {
    $insert = ("INSERT INTO ips (ip) VALUES ($ip)");
    $insertqry = $conn->query($insert);
}
 
$sql = ("SELECT times FROM ips WHERE ip='$ip'");
$qry = $conn->query($sql);
if ($qry < 5) {
    $sql = ("UPDATE ips SET times = times+1 WHERE");
    $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    $id = (int)$_GET['id'];
$qry= "UPDATE affiliate SET clicks = clicks+1 WHERE ID='$id'";
    $conn->query($qry);
$input = array("https://order.abcgam...f.php?aff=47", "https://discord.gg/CjzZRBq");
    $answer = array_rand($input, 1); //one key
header("Location: $input[$answer]"); //use the key to get the array element
} elseif ($qry > 5) {
    $input = array("https://order.abcgam...f.php?aff=47", "https://discord.gg/CjzZRBq");
    $answer = array_rand($input, 1); //one key
    header("Location: $input[$answer]"); //use the key to get the array element
}
?>
Edited by cyberRobot
added [code][/code] tags; indented code
Link to comment
Share on other sites

Read the forum rules, especially the part about proper code formatting.

 

Your code is fairly messed up. The reason for the error message is that you're trying to treat the return value of mysqli::query() -- which is a mysqli_result -- like an integer. That of course makes no sense. An SQL result set is not an integer, it's a result set. If you want to get a value from that set, you need to actually fetch it. mysqli has several methods for this.

 

But that's just one problem of many:

  • You have zero protection against SQL injection attacks. You happily insert all kinds of values straight into your query strings and hope that nothing happens, which is just naive. Learn to use prepared statements.
  • Dumping error messages on the screen is nonsensical. It helps attackers gain information about your system and at the same time irritates legitimate users. Either learn how to use mysqli properly or switch to PDO.
  • There are way too many queries for this simple task. You need four(!) queries just to increment the IP count. This can be done in one using INSERT INTO ... ON DUPLICATE KEY UPDATE ...
Edited by Jacques1
Link to comment
Share on other sites

None of this has anything to do with the problem.

 

As I already said above, the solution is to scrap the current code and use one query to simultaneously increment the IP counter and get the new value.

<?php

const IP_REQUESTS_LIMIT = 5;



/*
 * First try to insert the IP. If it already exists, increment the counter. In both cases, call LAST_INSERT_ID() with
 * the new counter value, so that the value can then by fetched by PHP. Alternatively, you could use a MySQL session
 * variable, but that would require an extra SELECT query.
 */
$ip_requests_stmt = $database_connection->prepare('
    INSERT INTO
      ips (ip, times) 
    VALUES
      (?, LAST_INSERT_ID(1))
    ON DUPLICATE KEY UPDATE
      times = LAST_INSERT_ID(times + 1)
');
$ip_requests_stmt->bind_param('s', $_SERVER['REMOTE_ADDR']);
$ip_requests_stmt->execute();

// get the counter value passed to LAST_INSERT_ID()
$ip_requests = $database_connection->insert_id;

if ($ip_requests <= IP_REQUESTS_LIMIT)
{
    echo 'Limit has not been reached yet (number of requests: '.$ip_requests.').';
}
else
{
    echo 'Limit has been reached';
}

Of course this requires the ip column to be a primary key or have a UNIQUE constraint, but I hope you've already done that.

Edited by Jacques1
  • Like 1
Link to comment
Share on other sites

None of this has anything to do with the problem.

 

Thanks for posting a more efficient method to solve the OPs problem. I mean that.

 

With that said, the OP mentioned he/she is getting an error. You vaguely addressed that and dalecosp just provided more concrete examples. While your code is more efficient, it is helpful for the OP to know what caused the error. This probably won't be the last time the error appears. And your solution will not always fix the issue.

Link to comment
Share on other sites

None of you addressed the problem. What the OP wants is to fetch a value. Not get a row count. There is just one row with a counter (the times column).

 

To fetch a value from a row, you use a fetch method. And I think I made that very, very clear in my reply:

 

The reason for the error message is that you're trying to treat the return value of mysqli::query() -- which is a mysqli_result -- like an integer. That of course makes no sense. An SQL result set is not an integer, it's a result set. If you want to get a value from that set, you need to actually fetch it. mysqli has several methods for this.

 

If you think the OP is too stupid to look those fetch methods up, I respectfully disagree.

Edited by Jacques1
Link to comment
Share on other sites

There's not a single line of code to get a row count, and a row count doesn't provide any useful information here. You two are reading something which doesn't exist into the code.

 

Pick any of the queries:

SELECT times FROM ips WHERE ip='$ip'

The OP wants the value of the times column which is a counter of the number of requests, as you can clearly see in the next query:

UPDATE ips SET times = times+1 WHERE ...

The only row count you would get is “1” over and over again.

 

 

If the OP had a different data model where a row count were in fact needed, I would happily accept that (though the row_count attribute is usually the wrong approach). But he just doesn't.

Edited by Jacques1
Link to comment
Share on other sites

There's not a single line of code to get a row count...

 

So this is not an attempt to get the row count? Note that I said "attempt".

if ($qry = 0) {
    $insert = ("INSERT INTO ips (ip) VALUES ($ip)");
    $insertqry = $conn->query($insert);
}
 
Basically, the OP is trying to insert a new row, if the previous query returned 0 results. Granted this could easily be replaced with by fetching the row as you said.
 
 
Ignore the example below. The number of rows isn't what the OP needs for that part. See Jacques1's comments above.  :happy-04:
 
 
How about this one?
if ($qry < 5) {
 
The OP wants the script to act differently when there are 5 results. Isn't it fair to say the OP is probably trying to access the number of rows?
Edited by cyberRobot
Link to comment
Share on other sites

The OP wants the value of the times column which is a counter of the number of requests, as you can clearly see in the next query:
UPDATE ips SET times = times+1 WHERE ...

The only row count you would get is “1” over and over again.

 

Yep, sorry about that. I was picturing a different database structure for some reason. Sorry about any confusion / frustration.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.