MYSQL SELECT statement with variable based on PHP loop - php

for ($i=1;$i<5;$i++) //Loop read & save all vars from fieldform
{
if (array_key_exists('country'.$i, $_POST) == true)
{
${"country".$i} = $_POST['country'.$i];
$get_id = mysqli_query($connection, "SELECT country_id FROM country WHERE country_pl = '{$country[$i]}'");
$row = mysqli_fetch_assoc($get_id);
$country_id = $row['country_id'];
echo $country_id;
}
}
This is a loop for read & save country name selected in form field. Everything works fine, beside MYSQL QUERY. I don't know how to write '{$country[$i]}' properly in a MySQL statement.

Don't use variable variables, use an array.
$country[$i] = mysqli_real_escape_string($connection, $_POST['country'.$i]);
Then you can do:
$get_id = mysqlil_query($connection, "SELECT country_id FROM country WHERE country_pl = '{$country[$i]}'");

It's better to run one query instead of one every iteration. I would suggest:
$countries = array();
for ($i=1;$i<5;$i++) //Loop read & save all vars from fieldform
{
if (array_key_exists('country'.$i, $_POST))
{
$countries[] = mysqli_real_escape_string($connection, $_POST['country'.$i]);
}
}
$get_id = mysqli_query($connection, "SELECT country_id FROM country WHERE country_pl IN ('" . implode ("', '", $countries) . "')");
while ($row = mysqli_fetch_assoc($get_id)) {
$country_id = $row['country_id'];
echo $country_id;
}
Ideally you should use a prepared statement, but that's a bit more tricky: see Trouble binding an imploded array into a mysql prepared statement

Related

PHP Creating variables list from Mysql database

I've a database that using for 3 languages this way:
id name de_de al_sq
1 title titel titulli
2 points punkte pike
Now when in php $lang is set to 'al_sq':
$lang = 'al_sq';
I'm trying to generate variables using names of that language, in this case:
$langtitle = 'titulli';
$langpoints = 'pike';
Trying something like:
$sql = "SELECT * FROM `langs`";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$lang{$row["lang"]} = $row[$lang];
}
}
but something is not good, how to generate these variables?
You have a minor syntax error in your code, which causes an error. What you need to do here is to:
Fetch the name and al_sq columns from the database table. This is done by selecting the value of $lang (based on your code). For security reasons, the value of $lang is protected against SQL injection, as you did not specify where the value was coming from.
Then you must check if there was any results, and in the case there wasn't any, it will simply terminate the script with an error.
Then lastly you must iterate over each row of the returned results, and do a variable variable assignment. This will make $langpoints etc. work (and any other you may add in the future).
Code:
$sql = 'SELECT `name`, `' . $conn->real_escape_string($lang) . '` FROM `langs`';
$result = $conn->query($sql);
if (!$result || !$result->num_rows) {
echo 'Invalid language selected';
exit;
}
while ($phrase = $result->fetch_assoc()) {
${'lang' . $phrase['name']} = $phrase[$lang];
}
// $langtitle
// $langpoints
It seems you are using the database as a key-value store with multiple value fields depending on the language, you could use PDO::FETCH_KEY_PAIR so it returns an array with the name as the key. This way you also avoid loading the data for other languages that you might not need at all:
$query = "SELECT `name`, :column as value FROM `langs`";
$statement = $pdo->prepare($query);
$statement->execute(["column" => $lang]);
$data = $statement->fetchAll(\PDO::FETCH_KEY_PAIR);
// $data becomes an array with the name as the key:
$langtitle = $data['title'];
$langpoints = $data['points'];
Make sure, if the user provides the value for $lang, to check that it is a valid column value.
This should be close to what you are wanting based on how your database is presented. Scaling up would be clunky though if there is more the title and points stored.
$lang = 'al_sq';
$sql = "SELECT $lang FROM 'langs'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$langtitle = $row[1];
$langpoints = $row[2];
}
}

php foreach returns last variable selected

the foreach doesn't seem to work correctly in which the last value selected is working but not all.
The array is selected from here:
<fieldset>
<legend>status:</legend>
<?php foreach ($statuss as $status): ?>
<div><label for="status<?php hscout($status['id']);
?>"><input type="checkbox" name="statuss1[]"
id="status<?php hscout($status['id']); ?>"
value="<?php hscout($status['id']); ?>"<?php
if ($status['selected'])
{
echo ' checked="checked"';
}
?>/><?php hscout($status['description']); ?></label></div>
<?php endforeach; ?>
</fieldset>
The index is as follows:
if (isset($_POST['statuss1']))
{
foreach ($_POST['statuss1'] as $status1)
{
$a = mysqli_real_escape_string($link, $status1);
$sql = "SELECT b FROM C WHERE d ='$a'";
$result = mysqli_query($z, $sql);
if (!$result)
{
$error = 'Still not working you.....';
include 'error.html.php';
exit();
}
$selected1s = array();
while ($row = mysqli_fetch_array($result))
{
$selected1s[] = $row['b'];
}
}
}
the $selected1s[] works only if one variable is selected. If multiple variables are selected, the last variable is parsed through.
Every time through the foreach loop that fetches the selected items, you say $selected1s = array(), which clears out the array you're using to accumulate them.
Take the line that says $selected1s = array(); and move it to before the foreach loop, if you just want to get this code working.
There's a way to build one query that gets all the rows at once, though. That typically beats the pants off doing a whole bunch of queries for one item each.
$selected1s = array();
if (!empty($_POST['statuss1'])) {
// Create a function that SQL-escapes and quotes an ID...
// (Note: requires PHP 5.3+)
$sqlify = function($id) use ($link) {
return "'" . mysqli_real_escape_string($link, $id) . "'";
};
// and apply it to the array to get back a list of SQL-ready values
$ids = array_map($sqlify, $_POST['statuss1']);
// string them together as a comma-separated list
$ids_sql = implode(',', $ids);
// and say `d IN (the list)`
$sql = "SELECT b FROM c WHERE d IN ($ids_sql)";
... do the query, fetch results into $selected1s
}
(This is the part where i'd normally advocate prepared statements and tell you to use them. Which you should, in most cases. For IN queries or the equivalent OR queries, though, they tend to suck.)

Multiple records with GET and PDO

Trying to figure out how to do this on multiple records. I am trying things out, looking at reference but not understanding how to get it working, firstly here Here is my code that works:
My href link in loop.
city
My PHP
if (isset($_GET['city'])) {
$city = $_GET['city'];
$stmt = $db->prepare("SELECT * from table WHERE city = ? ");
$stmt->execute(array($city));
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) : //loop starts
} else { //html content }
The above simply pulls city records that are being called via a URL variable in my first loop. What If wanted to repeat this multiple times with different URL Variables to generate different results from the database. So instead of just getting one record like my above code I want to get 2 more, here is a below example of what I mean.
Example Href links in a loop with the URL variables city, name country:
city
name
country
Example of PHP which is not working, but getting these URL variables and passing them through to mysql by SELECT, hopefully you get what I mean):
if (isset($_GET['city'], $_GET['name'], $_GET['country'])) {
$city = $_GET['city'];
$name = $_GET['name'];
$country = $_GET['country'];
$stmt = $db->prepare("SELECT * from table WHERE city = ? OR name = ? OR country = ?");
$stmt->execute(array($city, $name, $country));
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) : //loop starts
} else { //html content }
Any advice on how to achieve this would be appreciated, also if there is an easier way to do this or my current code is not up to scratch, please let me know. Thanks!
if (isset($_GET['city'])||isset($_GET['name'])||isset($_GET['country'])) {
echo $city= $_GET['city'];
echo $name=$_GET['name'];
echo $country $_GET['country'];
}
I think you're looking to put the url's into an array so that you can use them later? If so, you could do something like this:
if (isset($_GET['city'], $_GET['name'], $_GET['country'])) {
$city = $_GET['city'];
$name = $_GET['name'];
$country = $_GET['country'];
//added:
$url_array = array();
$stmt = $db->prepare("SELECT * from table WHERE city = ? OR name = ? OR country = ?");
$stmt->execute(array($city, $name, $country));
//$row changed to $rows
while($rows = $stmt->fetch(PDO::FETCH_ASSOC)) : //loop starts
//foreach added
foreach($rows as $row){
$url_array[] = $row;
}
} else { //html content }
I hope that helps?

PHP mySQL get table headers function

I'm trying to build a PHP function that allows me to have an array of the headers of MySQL database for finding a particular field.
function table($tablename,$id) {
$post = mysql_query("SELECT * FROM $tablename WHERE ID = '$id'");
}
How would I then output the table headers as effective miniature queries for the row in question.
eg. $post->title, $post->timestamp, $post->field4
You need MySQLi or PDO_MySQL, but in your case:
while ($row = mysql_fetch_assoc($post)) {
echo $row['title'];
}
Documentation
Remember that the use of mysql_* function is discouraged.
A simple PHP Script to fetch the field names in MySQL:
<?php
$sql = "SELECT * FROM table_name;";
$result = mysql_query($sql);
$i = 0;
while($i<mysql_num_fields($result))
{
$meta=mysql_fetch_field($result,$i);
echo $i.".".$meta->name."<br />";
$i++;
}
?>
OUTPUT:
0.id
1.todo
2.due date
3.priority
4.type
5.status
6.notes
Hope this helps! Taken from php.net documentation.
How about mysql_fetch_assoc($post)?
To get all field names int a seperate array:
$post = mysql_fetch_assoc($post);
$fields = array();
foreach($post as $title => $value){
$fields[] = $title;
}
You can use this in a while loop to go through all rows and get theri field values(as well as their names):
while($p = mysql_fetch_assoc($post)){
$title = $p['title'];
$timestamp = $p['timestamp'];
//And so on...
}
Edit: And Pierpaolo is right, you should use another mysql implementation as the old one is gonna be removed in PHP 5.5/5.6 or a bit later...
You can get just the column names by executing this:
DESCRIBE `MyTable`;
It will return a result set that contains Field, Type, Key, etc.
$query = mysql_query("DESCRIBE `MyTable`");
while($result = mysql_fetch_assoc($query)) {
echo $result['Field'] . "\n";
}

is_array for MySQL Select Statement with PHP

I have a basic PHP function that I am working with. Sometimes, it is passed an array of variables, and other times it is just passed one variable. So, currently, I have something like this:
<?
function do_this($user_id_array) {
$user_ids = array();
foreach ($user_id_array as $single_user_id) {
$sql = 'SELECT username FROM users
WHERE id = $single_unit';
while($row = mysql_fetch_assoc($result)) {
array_push($user_ids, $row['id'];
}
}
return $user_ids;
}
?>
My issue is this: If I call the function and send it only one variable (and not an array), it (obviously) gives me the following error: Invalid argument supplied for foreach()
My question is: How can I change this function in the most efficient way with the least amount of code? Do I have to use an if is_array() statement and just create 2 SELECT statements, one for each case (array and non-array)?
Many thanks!
I see several options:
Pass an array even if it's one element long
Test for is_array() and act accordingly
Add another argument which states whether to check for an int or an array.
I'd go with options 1 or 2, as option 3 is error prone.
Also, there might be a better solution to your problem, you shouldn't have a single query for every user, you should instead use the IN keyword in MySQL, something like this:
$users = (is_array($user_id_array)) ? implode(',',$user_id_array) : $user_id_array;
$query = "SELECT `username` FROM `users` WHERE `id` IN({$users})";
wow. that's a lot of queries. What about to delete foreach and do something like
if (is_array($user_id_array)){
$sql = 'SELECT username,id FROM users
WHERE id IN ('.implode(",", $user_id_array).')';
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result)){
$users[$row['id']] = $row;
}
}
You can write:
$user_id_array = (array)$user_id_array;
if (!is_array($user_id_array))
$user_id_array = array($user_id_array);
function do_this($user_id_array) {
$ids = array_map('intval', (array)$user_id_array);
$sql = 'SELECT username FROM users
WHERE id IN(' . implode(',', $ids) . ')';
$result = mysql_query($sql);
$usernames = array();
while ($row = mysql_fetch_assoc($result)) {
$usernames[] = row['id'];
}
return $usernames;
}
First line makes sure that you have an array ((array)$user_id_array) and that all values are valid integers. Then a single SQL query is executed for all user ids.

Categories