Doing multiple MySQL database activities at once in PHP - php

I'm creating a Reddit clone for web development class. Sorting posts by hotness is the final required thing for me to do.
What I'm struggling with, is binding hotness rating to database entry of given post on website. Because I'm already using a mysqli_query in the while loop, I can't start another query for adding hotness rating.
I read posts suggesting to use arrays but that would consume a lot of server resource since hotness would be calculated again on page refresh.
<?php
$link = mysqli_connect("localhost", "username", "password", "database");
if ($link === false) {
die("ERROR: Could not connect. " . mysqli_connect_error());
}
// this is just reddit's hotness algorithm
function hot($ups, $downs, $date) {
$s = $ups - $downs;
$order = log10(max(abs($s), 1));
if ($s > 0) {
$sign = 1;
} else if ($s < 0) {
$sign = -1;
} else {
$sign = 0;
}
$seconds = $date - 1134028003;
return round($sign * $order + $seconds / 45000, 2);
}
$query = "SELECT * from posts";
$result = mysqli_query($link, $query);
if($result) {
// goes through all posts for upvote/downvote values to calculate hotness
while ($row = mysqli_fetch_array($result)) {
$post_id = $row['post_id'];
$time_in_seconds = strtotime($row['timestamp']);
$hotness_rating = hot($row['upvotes'], $row['downvotes'], $time_in_seconds);
$hotness_query = 'UPDATE posts SET hotness=$hotness_rating WHERE post_id=$post_id';
// ideally this would add hotness to post's row in database
mysqli_query($link, $hotness_query);
}
} else {
echo mysqli_error($link);
}
?>

You should calculate "hotness" of topic on its update, such as up-vote, down-vote or new message and store it in database at that moment.
This will give you a "hotness" value in database without pointless* recalculations on every refresh and you could simply sort by "hotness".
These recalculations on every refresh is pointless, because if data isn't changed - you will get same result on every refresh and make useless updates to update to same value.

Related

connect to FTP using array values

I am new to php and struggling to get the data from a table in mysql and using it to connect to an ftp server. The table contains the external ip address of the ftp server, the base directory to change into and login credentials to use. I fetched the data from mysql and stored it in an array but while looping through it I get
php notice: trying to access array offset on type null.
Code:
$now = time();
$yesterday = $now - (24 * 60 * 60);
$date = date("Y-m-d", $yesterday);
if (isset($_GET['date'])) {
$date = $_GET['date'];
}
$startDate = "$date 00:00:00";
$endDate = "$date 23:59:59";
//$conn = &newEtConn();
$sql= "SELECT stager_usr, stager_pwd, stager_ip, basedir, view_direction from et_devices.cameras as a inner join et_params.stagers as b on a.stagerid = b.idstagers ";
$result = mysqli_query($conn,$sql);
$datas = array();
if (!$result) {
die ("table Connection problem");
}
if (mysqli_num_rows($result)>0){
while ($row = mysqli_fetch_assoc($result)){
$datas[] = $row;
}
print_r($datas);
}
if ($row!= "") {
foreach ($datas as $values) {
$ip_addr = $values['stager_ip'];
$login = $values['stager_usr'];
$password = $values['stager_pwd'];
$basedir = $values['basedir'];
if ($rows != "") {
$gotFtpConn = True;
$ftp_obj = ftp_connect($ip_addr, 21, 10) or $gotFtpConn = False;
if ($gotFtpConn) {
if (ftp_login($ftp_obj, $login, $passwd)) {
echo "could not connect" . $login;
return false;
}
return $newEtConn;
}
}
}
There are a few things that I don't like (and can improve)...
It looks like you intend to filter your database data based on a date, but then you never actually apply that value to the array. I'll help to clean up that process.
Your if ($row != '') check after the loop will always fail because the loop ONLY stops when $row becomes falsey.
The rest of your code looks like it only intends to process a single row in the result set (because it returns). I am going to assume that you have more conditional logic in your query's WHERE clause which ensures that only one row is returned -- otherwise, you shouldn't be using return in your loop.
$date = !empty($_GET['date']) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $_GET['date'])
? $_GET['date']
: date('Y-m-d', strtotime('yesterday'));
$sql = "SELECT stager_usr, stager_pwd, stager_ip
FROM et_devices.cameras AS a
JOIN et_params.stagers AS b ON a.stagerid = b.idstagers
WHERE DATE(a.some_datetime_column) = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $date);
$stmt->execute();
foreach ($stmt->get_result() as $row) {
$ftp = ftp_connect($row['stager_ip'], 21, 10);
if (!$ftp) {
throw new Exception('Failed to establish FTP connection');
}
if (!ftp_login($ftp, $row['stager_usr'], $row['stager_pwd'])) {
throw new Exception('Incorrect FTP login credentials');
}
return $ftp;
}
throw new Exception('FTP connection data not found');
If you experience a noticeable performance bottleneck with DATE() in your sql, then there are other techniques that may be faster, but they use longer/uglier syntax.

php store mysql result to memcache

I have a large amount of fetched rows in mysql table, it takes plenty of time to load the result everytime when the page is call, I might want to cache the result into php memcached to save loading time for every queries once the page loaded.
let say the query function is call:
class Account
{
public function get_account($mysqli)
{
$q = "SELECT * ";
$q .= "FROM `account`";
$sql = $mysqli->query($q);
if($sql->num_rows !== 0){
return $sql;
}
return false;
}
}
request the result:
$acc = new Account;
$m = new Memcache;
$m->addServer('localhost', 11211);
$ls = $acc->get_account($mysqli);
$html = '';
while($ob = $ls->fetch_object()){
$html .= '
<tr>
<td>'.$ob->name.'</td>
<td>'.$ob->phone.'</td>
<td>'.$ob->email.'</td>
<td>'.$ob->country.'</td>
</tr>';
}
in this case, how can I store the result into memcached? how can memcached know this result is stored and no MySQL query needed to load again?

Show numbers and names of connected users

I used to code in the old way in php and been introduced through this forum to POO.
I'm rewriting a script that was in mysql into PDO. This script is to show the numbers and the names of connected members on a website. So far it only displays the number but not yet the list of names of connected members
that the script updated:
<?php
session_start();
if(isset($_SESSION['nom'])){
include('class.connect.php');
include('class.user.php');
$db = new DBEngine();
//verify if the name is already in the table
$log = $db->con->prepare('SELECT COUNT(nom) AS name FROM members_connected WHERE nom=?');
$log->execute(array($_SESSION['nom']));
$count = $log->fetchColumn(0);
$time = time();
if ($count == 0)
{
// the user is not in the new table, i add him
$log = $db->con->prepare('INSERT INTO members_connected (nom,timestamp) VALUES(?,?)');
$log->execute(array($_SESSION['nom'],$time));
}
//name already in the table, update the timestamp
else
{
$log = $db->con->prepare('UPDATE members_connected SET timestamp=? WHERE nom=?');
$log->execute(array($_SESSION['name'],$time));
}
//5 min earlier's timestamp
$timestamp_5min = time() - (60 * 5);
$log = $db->con->prepare('DELETE FROM members_connected WHERE timestamp < ?');
$log-> execute(array($timestamp_5min));
$log = $db->con->prepare('SELECT nom FROM members_connected');
$log->execute();
$row = $log->fetch(PDO::FETCH_ASSOC);
echo $count ;
//show the list of connected
if($count > 0)
{
$i=0;
while($count = $log->fetch(PDO::FETCH_ASSOC));
{
$i++;
echo $count['nom'];
if($i<$row)
{
//space between names
echo ',';
}
}
}
}
?>
`
Any thoughts please ?
try adding the following after your second include;
$db = new DBEngine();
Then in the code where you have
$this->db->con->prepare(...
change that to
$db->con->prepare(...
UPDATE
In answer to your second error, it looks like you need to set the variable types in your bindings.
e.g.
$log->bindParam(1, $_SESSION['name'], PDO::PARAM_STR, 25);
$log->bindParam(2, time(), PDO::PARAM_STR, 20);
Alternatively, you don't need to bind variables like that and you could pass them directly into the execute like so (which is what you have in your first query btw)
$log->execute(array($_SESSION['name'], time()));
Create a TimeStamp class that will fetch and update your database like so:
class TimeStamp
{
protected $db;
public $row_count;
public function __construct($db)
{
$this->db = $db;
}
// This should grab all users connected
public function Fetch($_user, $interval = '1')
{
// This is just checking a time range and collecting names
// You may want to make a new function that will then take the return list and query your user info table to get the user info
$connected = $this->db->con->prepare("select * FROM members_connected WHERE timestamp > DATE_SUB(NOW(), INTERVAL $interval MINUTE)");
$connected->execute(array($_user));
if($connected->rowCount() > 0) {
while($result = $connected->fetch(PDO::FETCH_ASSOC)) {
$users[] = $result;
}
}
// This should get the count
$this->row_count = (isset($users))? count($users):0;
// Return if users are available
return (isset($users))? $users:0;
}
public function Record($_user)
{
$connected = $this->db->con->prepare("INSERT INTO members_connected (nom, timestamp) VALUES (:nom,NOW()) ON DUPLICATE KEY UPDATE timestamp = NOW()");
$connected->bindParam(':nom', $_user);
$connected->execute();
}
}
include('class.connect.php');
include('class.user.php');
$db = new DBEngine();
if(isset($_SESSION['nom'])) {
// Start the timestamp, feed database
$u_check = new TimeStamp($db);
// Record into db
$u_check->Record($_SESSION['nom']);
// Check db, print users
$users = $u_check->Fetch($_SESSION['nom']);
print_r($users);
// Display count
echo "USERS: ".$u_check->row_count;
}

Do-while loop hangs the connection to website

I am trying to use do-while loop to check if a value exists in database,
function check($a) {
$query = "SELECT * FROM `table` WHERE code = '$a'";
$result = mysql_query($query);
$nm = mysql_num_rows($result);
if ($nm > 0) {
return true;
} else {
return false;
}
}
function randomnumber() {
$chars = "abcdefghijkmnopqrstuvwxyz023456789";
srand((double)microtime()*1000000);
$i = 0;
$pass = '' ;
while ($i <= 10) {
$num = rand() % 33;
$tmp = substr($chars, $num, 1);
$pass = $pass . $tmp;
$i++;
}
return $pass;
}
$number = randomnumber();
do { $number = randomnumber(); } while (!check($number));
That codes somehow hangs the connection to website. After i execute this page, strangely it cannot connects to website until i restart the browser.
What may cause this ?
your query is never evaluating to true, so the loop is infinite. As long as it's not pulling back any rows where code = 'yourRandomNumber', then you will be looping indefinitely.
If you want to simply select a random 'code' from your database this code will be much more efficient than what you've got.
$query = 'SELECT DISTINCT code FROM `table`';
$result = mysql_query($query);
$my_arr = array();
while($row = $mysql_fetch_assoc($result)) {
$my_arr[] = $row['code']
}
$random_key = $my_arr[array_rand($my_arr)];
Re-reading your question and comments I'm less and less sure what your code originally set out to accomplish, if you could be a bit more clear on your objective here we could probably give you some advice on how to accomplish your goal more efficiently.
Edit:
This code will retrieve all of the codes already used in your table, calculate the difference from the possible codes, and then return one random unused code. No loop required. [well one loop, but it's a short one]
$psbl_codes = str_split("abcdefghijkmnopqrstuvwxyz023456789");
$query = 'SELECT DISTINCT code FROM `table`';
$result = mysql_query($query);
$used_codes = array();
while($row = $mysql_fetch_assoc($result)) {
$used_codes[] = $row['code']
}
$unused_codes = array_diff($psbl_codes, $used_codes);
echo "random unused code: " . $unused_codes[array_rand($unused_codes)];

Nested While Loops php

I've been trying to get a series of nested loops working to select the database name from one table then query the selected table in that database, and add up the results and display the number of them and the database name.
I have gotten the code to work but it keeps displaying:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in
I have tried every way possible I have found online to help, but none work.
$resulta = mysql_query("SELECT dbname AF012 FROM Customer");
while($data = mysql_fetch_array($resulta))
{
$db = $data[' dbname '];
$result = null;
$result2 = mysql_query("SELECT changemade FROM $db.orders");
//looping through the results
while($row = mysql_fetch_array($result2))
{
//checking if any record is 1,2 or 3
if( ($row[‘changemade’]== 1) || ($row[‘changemade’]== 2) || ($row[‘changemade’]== 3) ) {
//if any match the if adding 1 to the counter
$counter ++;
}
}
unset($result2);
echo $db." ".$counter;
echo "<br>";
$counter = 0;
$result = null;
$result2 = null;
}
All the database connections are made and work fine, so it has nothing to do with that. Any help would be great.
You need to introduce error handling, also you can streamline your code. The current point of failure is querying the database and fetching from it, so you can encapsulate it into a function of it's own which will also reduce your code:
function mysql_query_array($query)
{
if (!$result = mysql_query($query)) {
throw new Exception(sprintf('Invalid query "%s", error: %s.', $query, mysql_error()));
}
return function () use ($result) {
return mysql_fetch_array($result);
};
}
With that little helper function, your code is now more compact and it has actual error handling:
$queryA = mysql_query_array("SELECT dbname AF012 FROM Customer");
while ($data = $queryA())
{
$counter = 0;
$queryB = mysql_query_array("SELECT changemade FROM {$data['dbname']}.orders");
while ($row = $queryB())
{
if (in_array($row['changemade'], range(1, 3))) {
$counter++;
}
}
printf("%s %s<br>\n", $db, $counter);
}
This is caused by the fact that mysql_query return false if the query fails, so one of your query fails and mysql_fetch_array() gets a boolean. Try changing $db = $data[' dbname ']; to $db = $data['dbname'];

Categories