foreach function to create array from mysql db - php

need to return an array like this for example:
array(30 => 'Mercedes Benz 310 ',26 => 'Lamborghini Murcielago')
I have a database set up something like this:
CREATE TABLE cars (
id bigint(20) NOT NULL auto_increment,
`car_name` tinyint(2) NOT NULL default '0',
owner varchar(20) NOT NULL default ''
PRIMARY KEY (id)
) ENGINE=MyISAM;
The id need to be the array key.
So I tried to use foreach, but I have still not quite understood how it works.
$q = "select `id`, `car_name` from `cars` where `owner`='$username'";
$result = $conn->query($q);
unset($q);
if( !$result){
return array(0 => 'error');
}
$garage = $result->fetch_assoc();
$car_id = $garage["id"];
$car_name = $garage["car_name"];
foreach( $car_name as $key => $car_id ){
...
}

You aren't far off. Something like this should give you the kind of array you're looking for.
$q = "select `id`, `car_name` from `cars` where `owner`='$username'";
$result = $conn->query($q);
unset($q);
if( !$result){
return array(0 => 'error');
}
while($row = mysql_fetch_array($result)){
$garage[$row['id']] = $row['car_name'];
}
return $garage;

Related

stuck with multi-level categories and sub-categories php mysql

I do have a little directory listing products. Currently I can list Categories (level1) and sub-categories (level2).
I want to add potentially a 3rd level which would be sub-subcategories (level3).
Adding is working but listing (looping) does not work as it limits me to 2 levels.
I need some help to figure it out.
Here is the code for adding and listing and th mysql structure is:
CREATE TABLE `categories` (
`lcat_id` smallint(5) UNSIGNED NOT NULL,
`lcat_name` varchar(255) NOT NULL DEFAULT '',
`lcat_path` varchar(255) NOT NULL DEFAULT '',
`sub_cat` int(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
My code is:
<?php
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>?action=newcat" method ="POST">
Category Name : <input type = "text" name = "cat_name" maxlength="250"><br><br>
Sub of category : <select name="lcat_id">
<option value=''>0</option>
<?php
$sql_cat = mysqli_query($db_connect,"SELECT * from ".TABLE_CATS." WHERE sub_cat='0' ORDER BY lcat_id") or die(mysqli_error($db_connect));
while($row_cat = mysqli_fetch_array($sql_cat)) {
extract($row_cat);
/*
$id = $row_cat["lcat_id"];
$name = $row_cat["lcat_name"];
$sub_cat = $row_cat["sub_cat"];
*/
echo "<option value='".$row_cat["lcat_id"]."'>".$row_cat['lcat_name']."</option>";
$sql_subcat = mysqli_query($db_connect,"SELECT * from ".TABLE_CATS." WHERE sub_cat='".$row_cat["lcat_id"]."' ") or die(mysqli_error($db_connect));
while($row_subcat = mysqli_fetch_array($sql_subcat)) {
extract($row_subcat);
/*
$id = $row_subcat["lcat_id"];
$namea = $row_subcat["lcat_name"];
$sub_cata = $row_subcat["sub_cat"];
*/
echo "<option value='".$row_subcat['lcat_id']."'>-> ".$row_subcat['lcat_name']."</option>";
}
}
?>
</select>
<input type = "submit" value = "New Category"><br>
</form>
<?php
if ($_GET['action']=="newcat"){
if ($_POST['cat_name']==""){
print "You did not put anything.<br/>Go back";
}
$sql_cat = mysqli_query($db_connect,"SELECT lcat_name from ".TABLE_CATS." WHERE lcat_name='".$_POST['cat_name']."' ") or die(mysqli_error($db_connect));
while($row_cat = mysqli_fetch_array($sql_cat)) {
extract($row_cat);
$name = $row_cat["lcat_name"];
}
if ($row_cat['cat_name']){
print "Category <b>".$_POST['cat_name']."</b> already exists in <b>".$mysql_db."</b>.<br>Please chose new name.<br/>Go back";
}
$sql_subcat = mysqli_query($db_connect,"SELECT * from ".TABLE_CATS." WHERE sub_cat='".$row_cat['lcat_id']."' AND lcat_name='".$row_cat["lcat_name"]."'") or die(mysqli_error($db_connect));
while($row_subcat = mysqli_fetch_array($sql_subcat)) {
extract($row_subcat);
$namea = $row_subcat["lcat_name"];
$sub_cat = $row_subcat["sub_cat"];
}
if ($row_subcat['lcat_name']) {
echo ("Sub-category <b>".$row_subcat['lcat_name']."</b> already exists in <b>$mysql_db</b>. Please chose new name.<br/>Go back");
exit;
} else {
$sql_query = "INSERT INTO ".TABLE_CATS." (lcat_name, lcat_path, sub_cat) VALUES ('".$_POST['cat_name']."','".$_POST['cat_name']."','".$_POST['lcat_id']."')";
$result = mysqli_query($db_connect,$sql_query);
echo "You added category :<b> ".$_POST['cat_name']."</b> in <b>$mysql_db</b><br/>Go back.";
}
}
?>
I would start by improving your categories table by -
adding the primary key
adding a foreign key constraint for parent_id
removing redundant path column
and removing the column name prefix (the table is already called categories)
CREATE TABLE `categories` (
`id` SMALLINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`parent_id` SMALLINT UNSIGNED,
CONSTRAINT `fk_parent_category` FOREIGN KEY (parent_id) REFERENCES categories (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Instead of having nested loops running queries to get child categories, or a recursive function, I would use a recursive Common Table Expression (CTE) to build and return the category hierarchy -
WITH RECURSIVE nested_cats AS (
SELECT *, 0 `depth`, CAST(`name` AS CHAR(200)) AS `path`
FROM `categories`
WHERE `parent_id` IS NULL
UNION ALL
SELECT `c`.*, `nc`.`depth` + 1, CONCAT(`nc`.`path`, ' > ', `c`.`name`)
FROM `categories` `c`
JOIN `nested_cats` `nc` ON `nc`.`id` = `c`.`parent_id`
)
SELECT * FROM `nested_cats` ORDER BY `path`;
In your current code you are building up your SQL by concatenating strings with user input without any validation. This makes your script rather vulnerable to SQL Injection. You should take some time to understand prepared statements and how they help you to protect against SQLi. You are currently using MySQLi which provides support for prepared statements and parameterization but for my example I am using PDO, as I find it more intuitive.
<?php
// During development, report all PHP errors
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$pdo = new PDO('mysql:dbname=test;host=localhost', 'db_user', 'db_pass');
$feedback = '';
$action = filter_input(INPUT_POST, 'action');
/* IF IS POST DO ADD */
if ($action == 'New Category'){
$cat_name = filter_input(INPUT_POST, 'cat_name', FILTER_SANITIZE_SPECIAL_CHARS);
if (empty($cat_name)){
$feedback = 'You did not put anything.';
} else {
$parent_id = filter_input(INPUT_POST, 'parent_id', FILTER_VALIDATE_INT, ['options' => ['default' => null]]);
// check to see if it already exists
$statement = $pdo->prepare('SELECT `name` FROM `categories` WHERE `name` = :name');
// execute the prepared statement
$statement->execute(['name' => $cat_name]);
// retrieve result rows
$rows = $statement->fetchAll(PDO::FETCH_OBJ);
if ($rows) {
$feedback = "Category {$rows[0]->name} already exists!";
} else {
$stmt = $pdo->prepare('INSERT INTO `categories` (`name`, `parent_id`) VALUES (:name, :parent_id)');
$stmt->execute([':name' => $cat_name, ':parent_id' => $parent_id]);
$feedback = "You added category: <b>{$cat_name}</b>.";
}
}
}
/* LOAD ALL CATEGORIES */
$sql = '
WITH RECURSIVE `nested_cats` AS (
SELECT *, 0 `depth`, CAST(`name` AS CHAR(200)) AS `path`
FROM `categories`
WHERE `parent_id` IS NULL
UNION ALL
SELECT c.*, `nc`.`depth` + 1, CONCAT(`nc`.`path`, " > ", `c`.`name`)
FROM `categories` `c`
JOIN `nested_cats` `nc` ON `nc`.`id` = `c`.`parent_id`
)
SELECT * FROM `nested_cats` ORDER BY `path`';
$result = $pdo->query($sql);
$categories = $result->fetchAll(PDO::FETCH_OBJ);
?>
<form action="" method ="POST">
Category Name : <input type="text" name="cat_name" maxlength="250"><br><br>
Sub of category : <select name="parent_id">
<option value=""> - </option>
<?php
foreach ($categories as $category) {
$indent = str_repeat('-> ', $category->depth);
echo "<option value='{$category->id}'>{$indent}{$category->name}</option>\r\n";
}
?>
</select>
<input type="submit" name="action" value="New Category"><br>
</form>
<div><?php echo $feedback; ?></div>
This is only a crude example and has no error checking/handling but it should get you moving in a better direction.

MYSQL: Insert variables into variable name table

I am trying to insert PHP variables in a mysql table, where the table name is also a variable, using mysqli_query. I've tried multiple solutions from stackoverflow but it still does not work.
I try to do it like this, maybe I am missing something. Thank you in advance!
<?php
session_start();
#include_once "modules/connections/dbconn.php";
$value = $_POST['value'];
$playerid = $_SESSION["steamid"];
$playername = fetchinfo("name","users","steamid",$playerid);
$playeravatar = fetchinfo("avatar","users","steamid",$playerid);
$playercoins = fetchinfo("coins", "users","steamid",$playerid);
if($playercoins - $value < 0){
die(json_encode(array('message' => 'ERROR', 'code' => "Not enough coins!")));
}
$game = fetchinfo("value","parameters","name","raffleRound");
$maxitems = fetchinfo("value","parameters","name","raffleMaxritems");
$items = fetchinfo("itemsnum","rafflegames","id",$game);
$itemname = "Coins";
$itemavatar = "images/creditcardicon.png";
$color = "D2D2D2";
$initialvalue = fetchinfo("value","rafflegames","id",$game);
$from = $initialvalue * 100;
$to = $from + $value * 100;
$tablename = 'rafflegame'.$game;
if($items < $maxitems){
mysqli_query($GLOBALS["connect"], "UPDATE rafflegames SET `value`=`value`+$value, `itemsnum`=`itemsnum`+1 WHERE `id`=$game");
mysqli_query($GLOBALS["connect"], "UPDATE users SET `coins`=`coins`-$value WHERE `steamid`=$playerid");
mysqli_query($GLOBALS["connect"], "INSERT INTO `" . $tablename . "` VALUES ('".$playerid."', '".$playername."','".$itemname."','".$color."','".$value."','".$playeravatar."','".$itemavatar."','".$from."','".$to."')");
}
else {
die(json_encode(array('message' => 'ERROR', 'code' => "Too many items in the current game")));
}
?>
The other two queries work just fine.
The table structure is this:
mysqli_query($GLOBALS['connect'],"CREATE TABLE `rafflegame$roundNumber` (
`id` int(11) NOT NULL auto_increment,
`userid` varchar(70) NOT NULL,
`username` varchar(70) NOT NULL,
`item` text,
`color` text,
`value` float,
`avatar` varchar(512) NOT NULL,
`image` text NOT NULL,
`from` int NOT NULL,
`to` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;");
mysqli_query($GLOBALS['connect'],"TRUNCATE TABLE `rafflegame$roundNumber`");
There is difference between table structure and insert column coumnt, When you want id column as auto incremented in that case column name should be included in insert query.
Please use the code as below:
<?php
session_start();
#include_once "modules/connections/dbconn.php";
$value = $_POST['value'];
$playerid = $_SESSION["steamid"];
$playername = fetchinfo("name","users","steamid",$playerid);
$playeravatar = fetchinfo("avatar","users","steamid",$playerid);
$playercoins = fetchinfo("coins", "users","steamid",$playerid);
if($playercoins - $value < 0){
die(json_encode(array('message' => 'ERROR', 'code' => "Not enough coins!")));
}
$game = fetchinfo("value","parameters","name","raffleRound");
$maxitems = fetchinfo("value","parameters","name","raffleMaxritems");
$items = fetchinfo("itemsnum","rafflegames","id",$game);
$itemname = "Coins";
$itemavatar = "images/creditcardicon.png";
$color = "D2D2D2";
$initialvalue = fetchinfo("value","rafflegames","id",$game);
$from = $initialvalue * 100;
$to = $from + $value * 100;
$tablename = 'rafflegame'.$game;
if($items < $maxitems){
mysqli_query($GLOBALS["connect"], "UPDATE rafflegames SET `value`=`value`+$value, `itemsnum`=`itemsnum`+1 WHERE `id`=$game");
mysqli_query($GLOBALS["connect"], "UPDATE users SET `coins`=`coins`-$value WHERE `steamid`=$playerid");
mysqli_query($GLOBALS["connect"], "INSERT INTO `" . $tablename . "`(`userid`,`username`,`item`,`color`,`value`,`avatar`,`image`,`from`,`to`) VALUES ('".$playerid."', '".$playername."','".$itemname."','".$color."','".$value."','".$playeravatar."','".$itemavatar."','".$from."','".$to."')");
}
else {
die(json_encode(array('message' => 'ERROR', 'code' => "Too many items in the current game")));
}
?>

Can I replace a few query into one

I have some query call and I want to replace it into one but I don't know it is possible. My database looks like:
My database calls:
$minbet = $mysql->query('SELECT `value` FROM `jackpot1_info` WHERE `name`="minbet"')->fetch_assoc();
$minbet = $minbet['value'];
$maxbet = $mysql->query('SELECT `value` FROM `jackpot1_info` WHERE `name`="maxbet"')->fetch_assoc();
$maxbet = $maxbet['value'];
$maxitems = $mysql->query('SELECT `value` FROM `jackpot1_info` WHERE `name`="maxitems"')->fetch_assoc();
$maxitems = $maxitems['value'];
$maxitemsinpot = $mysql->query('SELECT `value` FROM `jackpot1_info` WHERE `name`="maxitemsinpot"')->fetch_assoc();
$maxitemsinpot = $maxitemsinpot['value'];
It's simple, just select name and value in a single query and you will have each name and value pair in a separate row:
$select = $mysql->query('
SELECT `name`, `value`
FROM `jackpot1_info`
WHERE `name` IN ("minbet","maxbet","maxitemsinpot","maxitems")
');
while ($result = $mysql->fetch_assoc())
{
var_dump($result);
}
Output would look like:
array(2) {
'name' =>
string(12884901894) "minbet"
'value' =>
int(123)
}
array(2) {
'name' =>
string(12884901894) "maxbet"
'value' =>
int(456)
}
...
I'm sure you can do the rest.
Use IN instead of = for one query.
$select = $mysql->query('SELECT name,value FROM `jackpot1_info` WHERE `name` IN ("minbet","maxbet","maxitemsinpot","maxitems")');
$result = $mysql->fetch_assoc();

mySQL->updating/inserting "compound" records

I have 2 tables structured like this:
CREATE TABLE `exp_ws_gk_text` (
`WGT_RID` INT(9) NOT NULL AUTO_INCREMENT,
`WGT_PRG_CODE` VARCHAR(5) NOT NULL,
`WGT_TEXT` VARCHAR(4000) NOT NULL,
INDEX `PrimaryKey` (`WGT_RID`)
)
CREATE TABLE `exp_ws_gk_state` (
`WGS_RID` INT(9) NOT NULL AUTO_INCREMENT,
`WGS_TYPE` INT(9) NOT NULL,
`WGS_STATE` VARCHAR(3) NOT NULL,
`WGS_WGT_RID` INT(9) NOT NULL,
INDEX `PrimaryKey` (`WGS_RID`),
INDEX `SecondaryKey` (`WGS_TYPE`, `WGS_STATE`)
)
This is how I query the data to be used in a site:
SELECT a.wgt_rid id, a.wgt_text text, a.wgt_prg_code prg_code,
b.wgs_state state, b.wgs_type type,
FROM exp_ws_gk_text a, exp_ws_gk_state b
WHERE a.wgt_rid = b.wgs_wgt_rid
I present the record with all the data returned. Now, when I want to edit or append a record, how would I save the data correctly if the data got sent from a form with these parameters:
$id = intval($_REQUEST['id']);
$prg_code = $_REQUEST['prg_code'];
$state = $_REQUEST['state'];
$crs_type = $_REQUEST['type'];
$text = $_REQUEST['text'];
An insert:
$sql = "BEGIN; ".
" INSERT INTO exp_ws_gk_text (WGT_PRG_CODE, WGT_TEXT) ".
" VALUES('".$prg_code."', '".$text."'); " .
" INSERT INTO exp_ws_gk_state (WGS_STATE, WGS_TYPE, WGS_WGT_RID) ".
" VALUES('".$state."', ".$course_type.", LAST_INSERT_ID()); ".
"COMMIT;";
$mysql_query($sql);
$sql = "SELECT WGS_WGT_RID id FROM exp_ws_gk_text WHERE WGS_RID = ".mysql_insert_id();
$result = mysql_query($sql);
$r = mysql_fetch_array($result, MYSQL_ASSOC);
echo json_encode(array(
'id' => $r["id"],
'prg_code' => $prg_code,
'state' => $state,
'type' => $type,
'text' => $text
));
A delete:
DELETE a, b FROM exp_ws_gk_text a
JOIN exp_ws_gk_state b ON a.WGT_RID = b.wgs_wgt_rid
WHERE a.WGT_RID = :id
$sql = "UPDATE exp_ws_gk_text a, exp_ws_gk_state b
SET a.WGT_PRG_CODE = ".$prg_code.", a.WGT_TEXT = ".$text.", b.WGS_STATE = ".$state.", b.WGS_TYPE = ".$crs_type."
WHERE
a.WGT_RID = ".$id." AND a.WGT_RID = b.wgs_wgt_rid";

Prepared statement returns same result during 'while'

I am trying to figure out why this while statement returns the same account ID each time. Below is the function I am using:
function Hourly(){
$sql = "SELECT * FROM users WHERE users.id IN(SELECT uid FROM point WHERE zoneid=1)";
$arr = array();
$user = $this->database->DBQry($sql, $arr);
$id = $user[0]['ID'];
$sql = "SELECT * FROM point WHERE zoneid > -1";
$arr = array();
$row = $this->database->DBCtr($sql, $arr);
$i=0;
while($i < $row){
$arr = array(":userid" => $id, ":zoneid" => 1, ":cash" => 500);
$this->database->DBIns($arr, 'cashtable');
echo"$id DONE!<br>";
$i++;
}
}
Here are my prepared statements I'm using.
// Query
function DBQry($sql,$arr){
$sth = $this->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute($arr);
$rs = $sth->fetchAll();
return $rs;
}
// Count
function DBCtr($sql,$arr){
$sth = self::prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute($arr);
return $sth->rowCount();
}
I think the issue I am encountering is with one of the statements.
What I am trying to achieve from the function is a result like this:
64 DONE!
80 DONE!
124 DONE!
648 DONE!
984 DONE!
1341 DONE!
1468 DONE!
1887 DONE!
2017 DONE!
2193 DONE!
2267 DONE!
But this is what comes out of the function:
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
64 DONE!
Code I am working from
<?
$DBHost = "localhost";
$DBUser = "user";
$DBPassword = "password";
$DBName = "db";
$Hcash=50;
$Link = MySQL_Connect($DBHost, $DBUser, $DBPassword) or die ("Can't connect to MySQL");
MySQL_Select_Db($DBName, $Link) or die ("Database ".$DBName." does not exist.");
$OnlineAccountQuery = Mysql_Query("SELECT * FROM point WHERE zoneid > -1");
$OnlineAccountNum = Mysql_Num_Rows($OnlineAccountQuery);
$i=0;
WHILE($i < $OnlineAccountNum){
$OnlineAccountArray = Mysql_Fetch_Array($OnlineAccountQuery);
$UID = $OnlineAccountArray['uid'];
MySQL_Query("INSERT INTO cashtable (userid, zoneid, cash) VALUES ($UID, 1, $Hcash)");
echo"$UID DONE!<br>";
$i++;
}
?>
Response to Shivan Raptor's Answer
function Hourly(){
$sql = "SELECT * FROM point WHERE zoneid > -1";
$arr = array();
$row = $this->database->DBCtr($sql, $arr);
$i=0;
while($i < $row){
$sql = "SELECT * FROM users WHERE users.id IN(SELECT uid FROM point WHERE zoneid=1)";
$arr = array();
$user = $this->database->DBQry($sql, $arr);
$id = $user[0]['ID'];
$arr = array(":userid" => $id, ":zoneid" => 1, ":cash" => 500);
$this->database->DBIns($arr, 'cashtable');
echo"$id DONE!<br>";
$i++;
}
}
Table Structures
CREATE TABLE `point` (
`uid` int(11) NOT NULL DEFAULT '0',
`aid` int(11) NOT NULL DEFAULT '0',
`time` int(11) NOT NULL DEFAULT '0',
`zoneid` int(11) DEFAULT '0',
`zonelocalid` int(11) DEFAULT '0',
`accountstart` datetime DEFAULT NULL,
`lastlogin` datetime DEFAULT NULL,
`enddate` datetime DEFAULT NULL,
PRIMARY KEY (`uid`,`aid`),
KEY `IX_point_aidzoneid` (`aid`,`zoneid`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `cashtable` (
`userid` int(11) NOT NULL,
`zoneid` int(11) NOT NULL,
`cash` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
You didn't overwrite $id. It's defined once before the while loop.
Please double check your logic.
UPDATE after question edit:
In your response's Hourly() function, $row should contain the count of rows of the first $sql. However, in the while loop, you're querying the 2nd same $sql again & again. Therefore, $id is always the same.
I think your 2nd query should relate to the result of first query, but you didn't. Consider joining 2 queries if possible.

Categories