PHP - Use Field Names as Variable [duplicate] - php

This question already has answers here:
Can I mix MySQL APIs in PHP?
(4 answers)
Closed 1 year ago.
I am getting the error "Warning: mysql_field_name() expects parameter 1 to be resource, object given in... on line 28"
I am fairly new to PHP, but what I am trying to accomplish is read a HTML file and replace a custom tag with the value of the record. The tag structure is |+FIELD-NAME-Record#+| For example if my sql returns two records for the "Name" field it will look for the following two tags |+Name1+| and |+Name2+| in the HTML file and replace it with the two returned values. Say Adam and Jim.
Below is the code that I have so far.
$c = '|+Name1+|<br>|+Name2+|';
echo(ReplaceHTMLVariables(mysqli_query($con,"SELECT * FROM nc_names"),$c));
function ReplaceHTMLVariables($results, $content){
while($row = mysqli_fetch_array($results)){
//Define a variable to count what record we are on
$rNum = 1;
//Loop through all fields in the record
$field = count( $row );
for ( $i = 0; $i < $field; $i++ ) {
//Use the field name and record number to create variables to look for then replace with the current record value
$content = str_replace("|+".mysql_field_name( $results, $i ).$rNum."+|",$row[$i],$content);
}
//move to next record
$rNum++;
}
return $content;
}
Line 28 references this line
$content = str_replace("|+".mysql_field_name( $results, $i
).$rNum."+|",$row[$i],$content);

You're mixing MySQL with MySQLi, and you don't really need to do all that if you pull mysqli_fetch_assoc() instead:
function ReplaceHTMLVariables($results, $content)
{
//Define a variable to count what record we are on
$rNum = 1;
/*** Using Mysqli::fetch_assoc() ***/
while( $row = mysqli_fetch_assoc( $results ) )
{
//Loop through all fields in the record
/*** Variable $value passed by reference for performance ***/
foreach( $row as $fieldName => &$value ) {
$content = str_replace("|+".$fieldName.$rNum."+|",$value,$content);
}
++$rNum; /*** Faster than $rNum++ **/
}
return $content;
}
mysqli_fetch_assoc() Pulls the data as an associative array, with the field name as the index key.

#Barmar comment is correct, you can't mix mysql_ and mysqli_ functions, which is why you are getting the error stated
I have also made some other changes to your code to simplify it. See inline comments for explanations
$c = '|+Name1+|<br>|+Name2+|';
// database query on separate line, not in function call, so we can catch any errors
$res = mysqli_query($con,"SELECT * FROM nc_names") or die(mysqli_error());
echo(ReplaceHTMLVariables($res,$c));
function ReplaceHTMLVariables($results, $content){
//Define a variable to count what record we are on
$rNum = 1;
// use fetch_assoc instead of fetch_array
// fetch_assoc will give you an array of column_name => value pairs
while($row = mysqli_fetch_assoc($results)){
// MOVED this outside the loop or you will reset to 1 it for each loop through
//Define a variable to count what record we are on
//$rNum = 1;
// extract column names from associative array
$field_names = array_keys($row);
//Loop through all fields in the record
// use foreach loop instead of for loop (this is just my preference, not essential) // $field = count( $row );
//for ( $i = 0; $i < $field; $i++ ) {
foreach ($field_names as $field_name) {
// Use the field name and record number to create variables to look for then replace with the current record value
// build placeholder on separate line, makes code easier to read
$placeholder = "|+{$field_name}{$rNum}+|";
$content = str_replace($placeholder, $row[$field_name], $content);
}
// move to next record
$rNum++;
}
return $content;
}

Related

How to check array for existing elements to assign ticket numbers?

I am attempting to create a function which will tell me what free numbers are available to use, I have a function which returns the numbers which have already been taken in an array.
I wish to check the returned array with existing elements against a blank array, and if the number is not in the array then push/add it to the empty array to allow me to return an array of available numbers/tickets.
I have tried some examples on here and looked upon PHP documentation on some items trying array_intersect, in_array etc.
I believe the best way to add the free numbers to the empty array is using array_push which has not been implemented into the example code as of yet.
Available numbers function so far:
function freeNumbers($drawID){
$minTickets = 1;
$maxTickets = totalTickets($drawID);
$takenNumbers = takenNumbers($drawID);
$freeNumbers = array();
for($i = 1; $i<$maxTickets; $i++){
$x = $i-1;
foreach($takenNumbers as $v){
if(in_array($v, $freeNumbers)){
echo "Element is in array";
break;
} else {
echo $v . "is taken";
}
}
}
//return $freeNumbers;
}
Taken numbers function
function takenNumbers($drawID){
$connect = new mysqli("localhost", "root", "", "dream");
$stmt = $connect->prepare("SELECT * FROM transaction WHERE DrawID = ?");
$stmt->bind_param("i", $drawID);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows == 0) exit("No rows");
$tickets = array();
while($row = $result->fetch_assoc()){
$id = $row['ID'];
$tickets[] = $row['TicketNumber'];
}
return $tickets;
}
Max tickets is just counting from a database transaction table to count already assigned numbers.
In this current iteration of the project, I am receiving the following "1 is taken" for each loop.
Thanks in advance, I have attempted to explain what I am attempting to do in best terms possible. But if I haven't been able to describe something please reply so I can explain it further.
Instead of checking on each array item, you could get the the difference values between all of the ticket numbers and the taken ticket numbers array using array_diff() :
function freeNumbers($drawID){
$minTickets = 1;
$maxTickets = totalTickets($drawID);
$takenNumbers = takenNumbers($drawID);
$freeNumbers = array();
$allTickets = range(1, $maxTickets);
$freeNumbers = array_values(array_diff($allTickets, $takenNumbers));
//return $freeNumbers;
}
Edit : added array_values() to reset the array index returned from the array_diff() function.
Edit : Or if you prefer to use the array_push() function, you could do it like :
for($i = 1; $i<$maxTickets; $i++){
if(!in_array($i, $takenNumbers)){
array_push($freeNumbers, $i);
}
}

Array push rows from SQL query

I am trying to save the rows (results) from an SQL query to a csv file.
I am using array push in order to put the results in a list. Later I put the data from this list to my csv file.
My code :
while ($row = $query->fetch_assoc())
{
echo sprintf( $row['campaign']);
array_push($list, $row['campaign']);
}
The results are there because sprintf works. The problem is with the syntax of array_push. I even tried :
array_push($list, array(''.$row['campaign']);
I am getting an error:
fputcsv() expects parameter 2 to be array
The full code is here :
$list = array
(
array('old_campaign_name', 'new_campaign_name')
);
// table 1
$sql = ('select distinct(campaign) as campaign from '.$table1.'');
// Run the query
$query = $Db->query($sql);
// Check for SQL errors
if ($Db->error)
{
return ($Db->error);
}
// Put data in the list
while ($row = $query->fetch_assoc())
{
echo sprintf( $row['campaign']);
array_push($list,$row['campaign'],'');
}
$fp = fopen($location, 'w');
foreach ($list as $fields)
{
fputcsv($fp, $fields);
}
fclose($fp);
As the error says, fputcsv expects each row that you put to be an array, so it can write it out with commas separating the elements. $list should be a 2-dimensional array, so you need to push an array onto it when you're building it.
while ($row = $query->fetch_assoc() {
$list[] = array($row['campaign']);
}
BTW, $list[] = x is equivalent to array_push($list, x).
When you initially create the $list array, it is an array containing one array. But when you add more values to it from your query results, you are pushing strings onto the end of it, not arrays. In effect, you will be making something like
$list = array (
array('old_campaign_name', 'new_campaign_name'),
'first campaign',
'second campaign',
'etc.',
...
);
Because of this, when you loop over $list, the first value should work with fputcsv, because it is an array, but any subsequent values will be strings instead of arrays and will cause the error you are seeing.
You should be able to fill the $list like this:
while ($row = $query->fetch_assoc()) {
$list[] = $row;
}
$list[] = $row will not overwrite the values previously in $list. From the PHP documentation for array_push:
Note: If you use array_push() to add one element to the array it's better to use $array[] = because in that way there is no overhead of calling a function.
It works like this :
while ($row = $query->fetch_assoc())
{
// array_push($list,$row['campaign'],'');
array_push($list,array($row['campaign'], ''));
}

Foreach loop declare different variable depend on select column

Ref : Foreach loop declare variable on select table array
OK ..... No more syntax error
Same question
Is it possible to create variable inside foreach loop that each variable name depend on column name that I select?
I've coded out like
$recid = $_GET['recid'];
//sql select string declaration
$sql = "select [Rec_ID],[Bike_ID],[Station],['Line']
from [rfttest].[dbo].[RFT_Records_Log]
where [Rec_ID] = {$recid}";
$query = sqlsrv_query($conn,$sql); //query
//if query fail print out error
if($query === false)
{
die(print_r(sqlsrv_errors(),true));
sqlsrv_close($conn);
}
//continue with fetch array
$recdata = sqlsrv_fetch_array( $query, SQLSRV_FETCH_ASSOC);
//foreach to declare variable
foreach($recdata as $x => $a)
{
$"$x" = $"$a";
}
Result should be
$Rec_ID = row rec_id data ,
$Bike_ID = row bike_id data,
$Station = row station data,
$Line = row line data
but i get these instead
$row rec_id data = row rec_id data ,
$row bike_id data = row bike_id data,
$row station data = row station data,
$row line data = row line data
You have two options.
One (the more secure one) is to use list():
list($Rec_ID, $Bike_ID, $Station, $Line) = $recdata;
This means that variable names can't overwrite variables by accident.
Two (the less secure one) is to use extract()
extract($recdata);
This turns an associative array into a number of variables, but by default will overwrite any variables with the same names that are set. This is the closest to what you're trying to do currently.
You can also pass a flag to extract to tell it not to overwrite existing variables (or to do a number of other things when there's a conflict).
extract($recdata, EXTR_SKIP);

Creating multidimensional array from existing arrays with variable variables

I'm creating a class function which accepts a mysql query result and returns a multidimensional array where the first array pointer is the table column and the second pointer is a numeric indicator of its position in the MySQL data.
Eg the table has the following columns:
Groupname
Groupid
Groupurl
And the way I want to call this is:
$arrayname[groupname][1];
I have formed 2 arrays already which are:
$colnames which contains all columns from the specific mysql query and
$$colname which is a variable variable of the column name containing all the data in each column. Eg: $groupurl is an array with all the data from that column.
I can't seem to get a loop to join the arrays as a multidimensional object and while I can manually do this for a specific table, it's a class function, and the variable variable part is breaking me =\
================ Thanks to IMSoP who gave me the idea, the solution is ==================
$result in the function is a successful MySQL Query on a table.
function tableAsMatrix($result)
{
//declare $results as array for use in loop
$results = array();
//this gets all the col names and sets them as $colnames[]
while( $cols = $result->fetch_field() )
{
$colnames[] = $cols->name;
}
//this loops through and assigns all cols as multidimensional $results[colname][id]
foreach ($colnames as $fields)
{
while ($row = $result->fetch_array(MYSQLI_ASSOC))
{
foreach($colnames as $field)
{
$results[$field][] = $row[$field];
}
}
}
//return to object
return $results;
}
The function I used is:
function tableAsMatrix($result)
{
//declare $results as array for use in loop
$results = array();
//this gets all the col names and sets them as $colnames[]
while( $cols = $result->fetch_field() )
{
$colnames[] = $cols->name;
}
//this loops through and assigns all cols as multidimensional $results[colname][id]
foreach ($colnames as $fields)
{
while ($row = $result->fetch_array(MYSQLI_ASSOC))
{
foreach($colnames as $field)
{
$results[$field][] = $row[$field];
}
}
}
//return to object
return $results;
}

MySQL select first 5 rows after query

I have a mysql result (having many rows) that I will use later. For now, I only need to access (sum) the first 5 rows. The problem is that the rows were saved from the query using "AS", so now they can be accessed by using $row['name'] . How can I select the first 5 rows without using the "name" for each of them?
Is there any way for doing like so:
PHP:
for($i=0;$i<5;++$i)
echo $row[$i];
?
EDIT
Sorry, my question was wrong.
Actually: How can I use the same $result 2 times without loosing the values by fetching the array?
What do you use for working with DB? PDO? MySQLi? MySQL extension?
If you use MySQL extension (mysql_connect(), mysql_query() etc), you can use mysql_data_seek() to move the internal row pointer of the MySQL result:
$res = mysql_query($sql);
if ( mysql_num_rows($res) ) {
// process first 5 lines
for ( $n = 0; $n < 5; ++$n ) {
$row = mysql_fetch_assoc($res);
if ( $row === false ) {
break;
}
// do something with $row
// ...
}
// reset pointer
mysql_data_seek($res, 0);
// process all rows
while ( $row = mysql_fetch_assoc($res) ) {
// do something with $row
// ...
}
}
mysql_free_result($res);
Another option would be to fetch all results into an array and then work with that array. I can't think of any benefit of holding MySQL resource opened.
$result = array();
while( $row = mysql_fetch_array($queryResult) ) {
$result[$row['primaryKey']] = $row; // index the $result according to any fieldValue(say primay key) so that you can access a single records without looping)
echo $row['name'];
}
use $result as many times as you want
you can use mysql query as
select * from table_name_ravi limit 0,5
just use this
I think you mix up things. $row['name'] accesses the column of a row with the name name sou you should work on your fetch function your while( $row = mysql_fetch_assoc($result) ) {}

Categories