Jonnyfencing1 Posted July 21, 2017 Share Posted July 21, 2017 (edited) 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 July 21, 2017 by cyberRobot added [code][/code] tags; indented code Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted July 21, 2017 Share Posted July 21, 2017 (edited) 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 July 21, 2017 by Jacques1 Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted July 21, 2017 Share Posted July 21, 2017 Read the forum rules, especially the part about proper code formatting. Some of that probably comes from the forum software. If the the OP uses tabs for indents they were likely removed by the forum. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted July 21, 2017 Share Posted July 21, 2017 I was talking about the lack of code tags. Quote Link to comment Share on other sites More sharing options...
dalecosp Posted July 21, 2017 Share Posted July 21, 2017 Bad: if ($qry = 0) {Good: if (!$qry || !$qry->num_rows) {Bad: if ($qry < 5) {Good: if ($qry->num_rows < 5) { 1 Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted July 24, 2017 Share Posted July 24, 2017 @Jonnyfencing1 - In case you're not aware, the following code doesn't handle cases where the number of rows is equal to 5: if ($qry->num_rows < 5) { //... } elseif ($qry->num_rows > 5) { //... } Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted July 24, 2017 Share Posted July 24, 2017 (edited) 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 July 24, 2017 by Jacques1 1 Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted July 24, 2017 Share Posted July 24, 2017 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. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted July 24, 2017 Share Posted July 24, 2017 (edited) 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 July 24, 2017 by Jacques1 Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted July 24, 2017 Share Posted July 24, 2017 None of you addressed the problem. What the OP wants is to fetch a value. Not get a row count. There are three lines of code attempting to get a row count. However, the point is kind of moot if the OP rightly chooses your solution. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted July 24, 2017 Share Posted July 24, 2017 (edited) 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 July 24, 2017 by Jacques1 Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted July 24, 2017 Share Posted July 24, 2017 (edited) 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. 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 July 24, 2017 by cyberRobot Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted July 24, 2017 Share Posted July 24, 2017 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.