I've got a bit of a problem with my code. I'm sure that it is something simple, but I just can't figure it out! I have been on tons of forums and have read several books... but every answer that I have worked to has failed. I almost guarantee that it's the way that I am using my syntax (and yes I know... procedural PHP is not really used anymore) but I am really a bit of a newbie to this and I am just trying to pick up the basics before moving onto OOP and PDO connections.
Could you please help me? At the moment I can get the user to select their date from the date picker and the results specifically from that date only will return... only problem is that the event is displaying the event_id as opposed to the name of the event that it relates to (1 = 5km run) for example.
Somehow I need to access the events table and pull the row that relates to that specific event_id.
I have normalized my database, and according to my tutor it looks ok. To give you an idea what it looks like - logins table (all user logins details), results table (a history of submitted events) events table (the events themselves).
On the results table the foreign keys are logins_id and the event_id. The primary key is the results_id in the results table and the only data stored here is the time and data (individual columns).
<?php // -----Stage 1. On submission of the form run the following -----//
if (isset($_POST['submit_d'])) {
$mydate = $_POST ['MyDate'];
$my = preg_replace('/[^a-zA-Z0-9]+/', ' ', $mydate);
if ($mydate) {
$result = mysql_query("SELECT * FROM logins WHERE username = '$username' LIMIT 1");
//This function will take the above query and create an array...
while($row = mysql_fetch_array($result))
{
//With the array created above, I can create variables (left) with the outputted array (right)
$logins_id3 = $row['logins_id'];
}
$sql = "SELECT * FROM results where $logins_id3 AND date = $mydate ";
/* ----- Here is the code that I want to use in conjunction with the above statement --->
$query = "SELECT logins.username,events.event,results.time,results.date,logins.age,logins.gender
FROM logins INNER JOIN results ON logins.logins_id=results.logins_id INNER JOIN events ON results.event_id=events.event_id
ORDER BY time ASC LIMIT 10";
*/
$resultz = mysql_query($sql);
if( mysql_num_rows($resultz) ) {
while ($row = mysql_fetch_array($resultz)) {
echo "<table><tr><th>Username</th><th>Event</th><th>Time (HH:MM:SS)</th><th>Date (YY/MM/DD)</th><th>Age</th><th>Gender</th>
</tr><tr><td>".$username."</td>"
."<td>".$row['event_id']."</td>"."<td>".$row['time']."</td>"." <td>".$row['date']."</td>"."<td>".$row['age']."</td>".
"<td>" $row['gender']."</td></tr></table>";
}
}
}
}
?>
The other thing I would like to do.. although this is not crucial, is to strip special characters from the input. Basically I'm using a jquery calendar picker and I want the user to be able to select their date in the 2014-05-26 format and the php to remove the - before it is submitted to the database, that way it doesn't effect the users experience but it will work with my current code.
Anyways sorry to waffle on, any help on either of these matters would be much appreciated!
Yours Sincerely:
Peter Scales.
You can use a join to get the data that relates to the event ID:
SELECT * FROM results r LEFT JOIN events e ON r.event_id = e.event_id WHERE ...
You can then select where "e.event_id = $event_id"; and the rest of your query logic.
You can also filter out any unwanted characters by using preg_replace: http://ar2.php.net/preg_replace
Related
I'm trying to count the unique visitors each day on my website.
This is the script i made:
<?php
require_once 'database.php';
$dateQuery = $db->prepare("SELECT count(*) AS hits FROM tracked GROUP BY DATE(date), hostadrr");
$dateQuery->execute();
$rows = $dateQuery->fetchAll(PDO::FETCH_ASSOC);
$array = array();
foreach ( $rows as $row ) {
$array[] = [(int)$row['hits']];
}
$json = json_encode($array);
echo $json;
?>
This array I get from the json_encode is then this:
[[3],[1],[1],[2],[10],[3],[1],[2]]
It is correct that there are 8 arrays inside an array, this represents each day. But the number inside each array are just the total number on clicks on my website, not grouped by the host address of the user. What am i doing wrong here? The array should be: [[1],[1],[1],[1],[1],[1],[1],[1]] (because i'm testing it on my own computer ;) )
First of all, always try to strip down your code to the minimal problem. For example, don't mix JSON encoding, PHP and MySQL and be astonished, that the result isn't what you look like.
Start with the SQL query:
SELECT count(*) AS hits FROM tracked GROUP BY DATE(date), hostadrr
Did you try to run that on console or in phpMyAdmin? Is the correct result showing up?
I would guess not. Why? Because this query only returns a number of hits without any relation to a date or a host address. So, even though you say that the data is correct for the total hits in a day, you can't even be sure if it is the right order or if it doesn't leave out days without any hits.
Since you do not provide your SQL schema, I can only assume one. But your query should at least look something like this:
SELECT
date AS date,
hostadrr AS host,
count(*) AS hits
FROM
tracked
GROUP BY
DATE(date),
hostadrr
ORDER BY
date ASC
Now, you'll get one line for each date/host combination along with the respective number of hits and you can assign that to an array, i.e.
$array[$row['date']][$row['host]] = (int) $row['hits'];
Hi there i am working on PHP code that is selecting columns from two tables.
Here is my code:
$result2 = mysql_query("SELECT *
FROM `videos`, `m_subedvids`
WHERE `videos.approved`='yes' AND
`videos.user_id`='$subedFOR'
ORDER BY `videos.indexer`
DESC LIMIT $newVID");
while($row2 = mysql_fetch_array($result2))
{
$indexer = addslashes($row2['videos.indexer']);
$title_seo = addslashes($row2['videos.title_seo']);
$video_id = addslashes($row2['videos.video_id']);
$title = addslashes($row2['videos.title']);
$number_of_views = addslashes($row2['videos.number_of_views']);
$video_length = addslashes($row2['videos.video_length']);
}
When i try to print $indexer with echo $indexer; it's not giving me any results.
Where is my mistake in this code?
It seems to me like the key 'indexer' isn't in your results. It's hard to tell, since you haven't listed a definition for your table and you're using SELECT * so we can't see the names.
It makes the program easier to read later, if instead of SELECT *..., you use SELECT col1, col2, .... Yes, SELECT * will save you some typing right now, but you'll lose that time later when you or anyone else who works on your code has to check the table definition every time they work with that line of code.
So, try changing your query to explicitly select the columns you use. If it's an invalid column you'll get an error right away rather than this silent failure you're getting now, and you'll thank yourself later as well.
So long as videos.indexer is a unique field name among all tables used in the query you can change
$indexer = addslashes($row2['videos.indexer']);
to
$indexer = addslashes($row2['indexer']);
You don't need to (or can not) use the table name when referring to the result.
This code is used to get a specific list of ID's from one table, then use those ID's to get the information from another table. Once I get all the information from the 2nd table, I am attempting to sort the data alphabetically based on a field in the 2nd table.
Example, I am getting the name based on a correlating ID and then want to display the entire result in alphabetical order by name (artist_name).
Here is the code I have. When I execute this without the sort(), it works fine but is not in alphabetical order. When I add the sort() in the 2nd while statement, the page looks the same but the name and other data do not display. The source code in the browser shows that the results are being accounted for but the sort must be preventing the variables or information from being displayed for some reason.
I haven't used a sort function before and I tried looking at some examples but couldn't really find something specific to my situation. Any and all help would be greatly appreciated. I have already looked at the PHP manual for sort so no need to send me a link to it ;-)
<?php $counter = 0;
$artistInfo = mysql_query("SELECT DISTINCT event_url_tbl.artist_id FROM event_url_tbl WHERE (SELECT cat_id FROM artist_tbl WHERE artist_tbl.artist_id = event_url_tbl.artist_id) = 1");
while ($aID = mysql_fetch_array($artistInfo))
{
$getArtistInfo = mysql_query("SELECT * FROM artist_tbl WHERE artist_id = '" . $aID['artist_id'] . "'");
while($artist = mysql_fetch_array($getArtistInfo))
{
sort($artist);?>
<a class="navlink" href="<?=HOST?><?=$artist['page_slug']?>/index.html">
<?=$artist['artist_name']?>
</a><br />
<?php }
}
?>
Your best bet, as a commenter mentioned, is to use an ORDER BY clause in SQL.
SELECT *
FROM artist_tbl
WHERE artist_id = XXX
ORDER BY artist_name ASC
The other commenter who suggested using PDO or mysqli is also correct, but that's a different issue.
To answer your specific question about sorting, according to the manual,
Blockquote Note: This function assigns new keys to the elements in array. It will remove any existing keys that may have been assigned, rather than just reordering the keys.
This means all of your array keys ('page_slug', 'artist_name', etc) are wiped out. So when you try to refer to them later, there is no data there.
Were you to use this method, you would want to use asort to sort an associative array.
However, you don't want to use sort here. What you're sorting is the variables for one row of data (one individual artists), not all of your artists. So if you think of each artist row as an index card full of data (name, id#, page slug, etc) all you're doing is moving those items around on the card. You're not reorganizing your card catalog.
Using an order by clause in the SQL statement (and rewriting in PDO) is your best bet.
Here is how I would rewrite it. I have to take some guesses at the SQL because I'm not 100% sure of your database structure and what you're specifically trying to accomplish, but I think this would work.
$query_str = "
SELECT
artist.name,
artist.page_slug
FROM
artist_tbl AS artist
INNER JOIN event_tbl AS event
ON event.artist_id = artist.artist_id
WHERE
artist.cat_id = 1
ORDER BY
artist.name ASC";
$db_obj = new PDO (/*Connection stuff*/);
$artists_sql = $db_obj->prepare ($query_str);
$artists_sql->execute ();
while ($artist = $artists_sql->fetch (PDO::FETCH_ASSOC)) {
$return_str .= "<a class='navlink' href='{HOST}
{$artist['page_slug']}/index.html'>
{$artist['artist_name']}</a><br/>";
}
echo $return_str;
In all honesty, I would probably create an artist class with a display_link method and use PDO's fetchObject method to instantiate the artists, but that's getting ahead of ourselves here.
For now I stuck with procedural code. I don't usually like to mix my HTML and PHP so I assign everything to a return string and echo it out at the end. But this is close to what you had, using one SQL query (in PDO - seriously worth starting to use if you're creating new code) that should give you a list of artists sorted by name and their associated page_slugs.
You could do all of this in one query:
SELECT * FROM event_url_tbl AS event
INNER JOIN artist_tbl AS artist ON event.artist_id = artist.id
ORDER BY artist.name DESC;
This cuts out a lot of the complexity/foreaches in your script. You'll end up with
Label1 (Label 1 details..) Artist1 (Artist1 details..)
Label1 (Label 1 details..) Artist2 (Artist1 details..)
Label2 (Label 2 details..) Artist3 (Artist1 details..)
Always good to bear in mind "one query is better than many". Not a concrete rule, just if it's possible to do, try to do it. Each query has overheads, and queries in loops are a warning sign.
Hopefully that helps
I'm trying to create an array, and then sort the objects by time, from a mysql_query.
This is what happens:
When a player has completed his turn, I update the database. I set the database variable "lastTurn" to the current time.
$nickname = $_POST['name'];
$lastTurn = date();
$myTurn = NO;
$query ... update query
Now I need to find out who the next player is, and send the turn to him/her.
$query = "SELECT * FROM active_users_table WHERE match_id='12345'
This gives me all the player associated with the current game.
But now I don't know how to continue.
I want to put all the players into an array, and then sort it after turnDate i guess, to see who the next player is. Like a poker game. I also need to check another variable in the database, "havePlayerLost", to see if he still is active in the game. If he have lost, then get the next player who is active, and with the highest turnDate.
Any advice is very appreciated.
Thanks
I would suggest you let MySQL/SQL do a little more work than you're doing right now. The SQL query you use to update the player, can also contain the current date / time in the right format.
player_lastTurn = NOW()
When it comes to sorting your array, I'd suggest you let MySQL handle this one aswell:
ORDER BY player_lastTurn ASC
ASCending means it will give you the oldest DateTime for that cellname within the entire database.
When you use the results of these queries and build your array using it, you're array will automatically be in the correct order.
The same applies for the "lost players", so you automatically not include them in the array when you're not loading it.
To get the player sorted try to change the query adding ' ORDER BY turnDate ASC '
$query = "SELECT * FROM active_users_table WHERE match_id='12345' ORDER BY turnDate ASC"
For the variable "havePlayerLost" I think you can change the query too like this adding ' havePlayerLost = false '
$query = "SELECT * FROM active_users_table WHERE match_id='12345' AND havePlayerLost = false ORDER BY turnDate ASC"
try this query
$query = "SELECT * FROM active_users_table WHERE match_id='12345'
and status !='havePlayerLost'
order by lastTurn Asc
I'm having problems debugging a failing mysql 5.1 insert under PHP 5.3.4. I can't seem to see anything in the mysql error log or php error logs.
Based on a Yahoo presentation on efficient pagination, I was adding order numbers to posters on my site (order rank, not order sales).
I wrote a quick test app and asked it to create the order numbers on one category. There are 32,233 rows in that category and each and very time I run it I get 23,304 rows updated. Each and every time. I've increased memory usage, I've put ini setting in the script, I've run it from the PHP CLI and PHP-FPM. Each time it doesn't get past 23,304 rows updated.
Here's my script, which I've added massive timeouts to.
include 'common.inc'; //database connection stuff
ini_set("memory_limit","300M");
ini_set("max_execution_time","3600");
ini_set('mysql.connect_timeout','3600');
ini_set('mysql.trace_mode','On');
ini_set('max_input_time','3600');
$sql1="SELECT apcatnum FROM poster_categories_inno LIMIT 1";
$result1 = mysql_query($sql1);
while ($cats = mysql_fetch_array ($result1)) {
$sql2="SELECT poster_data_inno.apnumber,poster_data_inno.aptitle FROM poster_prodcat_inno, poster_data_inno WHERE poster_prodcat_inno.apcatnum ='$cats[apcatnum]' AND poster_data_inno.apnumber = poster_prodcat_inno.apnumber ORDER BY aptitle ASC";
$result2 = mysql_query($sql2);
$ordernum=1;
while ($order = mysql_fetch_array ($result2)) {
$sql3="UPDATE poster_prodcat_inno SET catorder='$ordernum' WHERE apnumber='$order[apnumber]' AND apcatnum='$cats[apcatnum]'";
$result3 = mysql_query($sql3);
$ordernum++;
} // end of 2nd while
}
I'm at a head-scratching loss. Just did a test on a smaller category and only 13,199 out of 17,662 rows were updated. For the two experiments only 72-74% of the rows are getting updated.
I'd say your problem lies with your 2nd query. Have you done an EXPLAIN on it? Because of the ORDER BY clause a filesort will be required. If you don't have appropriate indices that can slow things down further. Try this syntax and sub in a valid integer for your apcatnum variable during testing.
SELECT d.apnumber, d.aptitle
FROM poster_prodcat_inno p JOIN poster_data_inno d
ON poster_data_inno.apnumber = poster_prodcat_inno.apnumber
WHERE p.apcatnum ='{$cats['apcatnum']}'
ORDER BY aptitle ASC;
Secondly, since catorder is just an integer version of the combination of apcatnum and aptitle, it's a denormalization for convenience sake. This isn't necessarily bad, but it does mean that you have to update it every time you add a new title or category. Perhaps it might be better to partition your poster_prodcat_inno table by apcatnum and just do the JOIN with poster_data_inno when you need the actually need the catorder.
Please escape your query input, even if it does come from your own database (quotes and other characters will get you every time). Your SQL statement is incorrect because you're not using the variables correctly, please use hints, such as:
while ($order = mysql_fetch_array($result2)) {
$order = array_filter($order, 'mysql_real_escape_string');
$sql3 = "UPDATE poster_prodcat_inno SET catorder='$ordernum' WHERE apnumber='{$order['apnumber']}' AND apcatnum='{$cats['apcatnum']}'";
}