-
Posts
24,420 -
Joined
-
Last visited
-
Days Won
805
Posts posted by Barand
-
-
I'll second that - use PDO.
I originally switched from MySQL_ functions to mysqli_ ones . Some time later I decided to give PDO a go and wished I'd done it years earlier.
EDIT:
mysqli looks tempting because looks as though all you have to do is add the letter "I" to the function calls - you can't.
With mysqli, if you use the query() function you get a "result" object. If you use prepare() you get a "statement" object. The functions you use to process the query results from these two object types are different ( Confusing, you get the impression it was developed by two separate teams who didn't speak to one another).
With PDO you get the same object type with both methods and therefore only one set of processing functions to worry about. What's more, they are easier to use than the equivalent mysqli versions.
-
Thanks. One never stops learning in this game.
-
9 hours ago, maxxd said:
I think that exact code is one of the main reasons jQuery blew up as big as it did as quickly as it did.
+1. I can't understand why anyone would not use jQuery for AJAX requests.
As you are just fetching data to display on the page you should be using GET method and not POST.
Change to $_GET and test your "urlpost.php" page on its own in your browser, passing the "url=www.facebook.com" in the query string. Any errors should the become evident.
-
I changed to function below so it returns "false" if the keyword is not found.
If the matched item is the first in the array its index will be "0" so your test for
if ($index)
will fail as 0 evaluates to false. You need to explicitly test for a Boolean false as below
function array_search_partial($arr, $keyword) { foreach ($arr as $index => $string) { $userBase = basename($string); $test = substr_count($userBase, '-'); if($test === 2) { if(preg_split("/[-]+/", $userBase)[2] == $keyword) { return $index; } } } // if we get here it hasn't found the keyword return false; } $index = array_search_partial($profilePaths, $userName); if($index !== false){ // check it isn't (boolean) false $profileLink = "/".$profilePaths[$index].".html"; }
-
Do you test your code? Aside from the logic being wrong it is also missing a "}"
In the code below using your function, a search for "dinosaur64"" should return "1"
$filepaths = array(); $filepaths[] = "/path/to/file/bob-villa-bvilla35"; $filepaths[] = "/path/to/file/jim-bob-dinosaur64"; $filepaths[] = "/path/to/file/abe-lincoln-alinkler"; $filepaths[] = "/path/to/file/michael-jordan-ncairman"; $filepaths[] = "/path/to/file/bart-simpson-eatmyshorts"; function array_search_partial($arr, $keyword) { foreach ($arr as $index => $string) { $userBase = basename($string); $test = substr_count($userBase, '-'); if($test === 2) { if(preg_split("/[-]+/", $userBase)[2] == $keyword) { return $index; } else { return false; } } } } $index = array_search_partial($filepaths, 'dinosaur64'); var_dump($index); //--> bool(false) (Should be "1")
27 minutes ago, nephesh said:It will always find something.
You can guarantee that no-one will search for a keyword that isn't there?
(At the moment it will only ever find the first item.)
-
10 minutes ago, kilnakorr said:
using a while loop will just output '10 12 15'
It will if you only out put the total column - but the animal type is there too...
mysql> CREATE TABLE myanimal (animal varchar(10) ); Query OK, 0 rows affected (0.55 sec) mysql> INSERT INTO myanimal VALUES ('cat'),('dog'),('cat'),('dog'),('horse'),('horse'),('duck'),('dog'),('cat'); Query OK, 9 rows affected (0.06 sec) Records: 9 Duplicates: 0 Warnings: 0 mysql> select * from myanimal; +--------+ | animal | +--------+ | cat | | dog | | cat | | dog | | horse | | horse | | duck | | dog | | cat | +--------+ 9 rows in set (0.00 sec) mysql> select animal -> , count(*) as total -> FROM myanimal -> GROUP BY animal; +--------+-------+ | animal | total | +--------+-------+ | cat | 3 | | dog | 3 | | duck | 1 | | horse | 2 | +--------+-------+
In PHP...
$res = $db->query("SELECT animal , COUNT(*) as total FROM myanimal GROUP BY animal "); $totals = []; foreach ($res as $row) { $totals[ $row['animal'] ] = $row['total']; } // now you can access each animal's total echo $totals['horse']; //--> 2 echo $totals['dog']; //--> 3
-
SELECT animal , COUNT(*) as total FROM mytable GROUP BY animal;
https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html
-
Alternatively you can do it in the query by defining the condition for each column and setting it 0 or 1 then SUMMING the columns grouped by class
I have only done the first five columns but you should get the idea
SELECT classroomname as Classroom , COUNT(*) as Enrolled , SUM(cconly) as `CC Only` , SUM(ehspi) as `EHS/PI` , SUM(ccpi) as `CC/PI` , SUM(ehsccpi) as `EHS/CC/PI` FROM classrooms JOIN ( SELECT classroomID , CASE WHEN childcaretype IS NOT NULL AND hstype IS NULL AND cpsstatus IS NULL THEN 1 ELSE 0 END as cconly , CASE WHEN hstype = 'EHS' AND (cpsstatus = 'PI PEN' OR cpsstatus = 'PI APP') THEN 1 ELSE 0 END as ehspi , CASE WHEN childcaretype IS NOT NULL AND (cpsstatus = 'PI PEN' OR cpsstatus = 'PI APP') THEN 1 ELSE 0 END as ccpi , CASE WHEN childcaretype IS NOT NULL AND hstype = 'EHS' AND (cpsstatus = 'PI PEN' OR cpsstatus = 'PI APP') THEN 1 ELSE 0 END as ehsccpi FROM children ) as childs USING (classroomid) GROUP BY classroomname;
+-----------+----------+---------+--------+-------+-----------+ | classroom | Enrolled | CC Only | EHS/PI | CC/PI | EHS/CC/PI | +-----------+----------+---------+--------+-------+-----------+ | Room 1 | 13 | 5 | 1 | 3 | 1 | | Room 2 | 12 | 3 | 1 | 3 | 1 | | Room 3 | 16 | 2 | 2 | 5 | 2 | | Room 4 | 18 | 5 | 0 | 4 | 0 | | Room 5 | 10 | 4 | 0 | 0 | 0 | | Room 6 | 12 | 2 | 1 | 2 | 1 | | Room 7 | 12 | 4 | 1 | 2 | 1 | +-----------+----------+---------+--------+-------+-----------+
It would better if the cpsstatus were two columns
- PI or PFA
- AP or PEN
-
I am curious about this line that you posted earlier. (You don't show us where you set that $interval value)
$interval = DateInterval::createFromDateString($interval);
Immediately before that line put
var_dump($interval);
and post the output. (You don't show us where you set that value)
-
I ran
if(isset($_POST['datestop'])){ $today = date("Y-m-d"); $datestop=$_POST['datestop']; // assuming $datestop now contains '2019-10-15' echo "$today<br /><br />$datestop<br /><br />"; $begin = new DateTime($today); $end = new DateTime($datestop); }
- no errors!
then added
$period = new DatePeriod($begin, new DateInterval('P1D'), $end); foreach ($period as $d) { echo $d->format('jS F Y') . "<br>\n"; }
giving
Quote8th October 2019
9th October 2019
10th October 2019
11th October 2019
12th October 2019
13th October 2019
14th October 2019 -
9 minutes ago, jakebur01 said:
$begin = DateTime($today);
$end = DateTime($datestop);
You have removed the "new"s
Should be
$begin = new DateTime($today); $end = new DateTime($datestop);
BTW error messages have line numbers to tell you where it happened.
-
Post the full error message too
-
I suspect this is the code causing the error
// do other tasks
-
Shame on me for missing that!
@techker To save having to test if every mysqli function call worked or not, tell it to throw an exception automatically. It keeps your code a lot cleaner. Call mysqli_report() before you connect to the db.
mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT); $mydb = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
-
I see nothing in that code that would give that error.
FYI. don't put a single string variable inside quotes as you have
$end = new DateTime("$datestop"); ^ ^
It's inefficient and unnecessary. Just use
$end = new DateTime($datestop);
-
Are you saying that when you select "1" from the dropdown then $_GET['cr'] contains "2"
You don't show your <select> tag - can you confirm the name = 'cr' ?
It looks OK but check the source code of your form page to make sure the menu is built correctly.
Some general points …
- As you are updating data your form method should be POST and not GET
- strip_tags hasn't been required since magic_quotes were deprecated decades ago
- mysqli_real_escape_string is not used with prepared queries,
-
FYI, if you are considering the JSON route suggested by @requinix there is a MySQL example here
-
So I guess you'd have a front-end form for the user so they can select various options ( varying depending on the survey) and then submission of the form would generate the above query and execute it.
The challenge then becomes the program which, given a specific survey, will generate that front-end form.
-
You don't show the query so I'm going to guess the results are from using a join.
If you have
tableA tableB +-----------+--------------+ +------+-----------+-------+ | a_id | name | | b_id | cola | a_id | +-----------+--------------+ +------+-----------+-------+ | 1 | Curly | | 1 | aaa | 1 | | 2 | Larry | | 2 | bbb | 2 | +-----------+--------------+ | 3 | ccc | 1 | | 4 | ddd | 1 | | 5 | eee | 1 | | 5 | fff | 2 | | 5 | ggg | 2 | | 5 | hhh | 2 | +------+-----------+-------+ SELECT a.name , b_id , cola FROM tablea a INNER JOIN tableb b ON a.a_id = b.a_id WHERE a.a_id = 1
then the results will be
+---------+--------+--------+ | name | b_id | cola | +---------+--------+--------+ | Curly | 1 | aaa | | Curly | 3 | ccc | | Curly | 4 | ddd | | Curly | 5 | eee | +---------+--------+--------+
where "Curly" is repeated 4 times because for the record in tablea there are 4 matching records in tableb with matching values in column a_id.
That's the nature of joins. Live with it.
A common way is to rearrange the data thus
data['Curly'] = [ 1 => aaa, 3 => ccc, 4 => ddd, 5 => eee ]
-
The simple part is creating an application to create different surveys. The hard part is an app for analyzing the results of any survey that is thrown at it.
You are going to have infinite combinations of different types of answer
- simple Boolean (Y/N)
- single value number/date/text(avoid)
- single choice list
- multiple choice list
- value ranges (crap, poor, OK, good, excellent)
with
- cross-tabulations/pivot tables between any two responses (eg average/count/total of X for each Y)
- Frequency charts to analyze responses
I suppose it's a bit like printers (sell it cheap and make your money selling the ink cartridges). In this case you sell the ability to create surveys then monetize it by selling customised analysis services.
Something like this should work
-
This is my test version (with a couple of extra displays to confirm the processing)
<?php ## connect to your DB here ## $userid = '0'; $subid = '0'; $cr = 0; $max = 0; $confirm = ''; $before = $after = ''; // // was data posted? // if ($_SERVER['REQUEST_METHOD']=='POST') { $userid = $_POST['userid'] ?? 0; $subid = $_POST['subid'] ?? 0; $cr = $_POST['credits'] ?? 0; $before = "<h3>Before</h3>" . query2HTML($db, "select * from codes where userid in ($userid, $subid)"); $stmt = $db->prepare("UPDATE codes SET UserId = ? WHERE UserId = ? AND status != 'Used' LIMIT ? "); $stmt->bind_param('iii', $subid, $userid, $cr); $stmt->execute(); $howmany = $db->affected_rows; if ($cr==$howmany) { $confirm = "<div style='display:inline-block; padding: 16px; background-color: #EEE; color: #000'>$howmany rows transferred</div><br>"; } else { $confirm = "<div style='display:inline-block; padding: 16px; background-color: #F00; color: #FFF'>$howmany rows transferred</div><br>"; } $after = "<h3>After</h3>" . query2HTML($db, "select * from codes where userid in ($userid, $subid)"); } // // respond to ajax request // if (isset($_GET['ajax'])) { exit(cr_options($db, $_GET['userid'], 0)); } /** * create list of credit quantity options * * @param mysqli $db * @param int $user * @param int $current - current quantity */ function cr_options(mysqli $db, $user, $current) { $stmt = $db->prepare("SELECT COUNT(*) as tot FROM codes WHERE status != 'Used' AND UserId = ? "); $stmt->bind_param('i', $user); $stmt->execute(); $stmt->bind_result($tot); $stmt->fetch(); if ($tot == 0) { $opts = "<option value=''>No unused codes</option>"; } else { for($i=1; $i<=$tot; $i++) { $sel = $i==$current ? 'selected' : ''; $opts .= "<option $sel>$i</option>"; } } return $opts; } /** * general purpose debugging utility function to output query results * * @param mysqli connection $db * @param string $sql * @return string - html table */ function query2HTML($db, $sql) { $output = "<table border='1' cellpadding='2' style='border-collapse:collapse'>\n"; // Query the database $result = $db->query($sql); // check for errors if (!$result) return ("$db->error <pre>$sql</pre>"); if ($result->num_rows == 0) return "No matching records"; // get the first row and display the headings $row = $result->fetch_assoc(); $output .= "<tr><th>" . join('</th><th>', array_keys($row)) . "</th></tr>\n"; // display the data do { $output .= "<tr><td>" . join('</td><td>', $row) . "</td></tr>\n"; } while ($row = $result->fetch_assoc()); $output .= "</table>\n"; return $output; } ?> <html> <head> <meta http-equiv="content-language" content="en"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Sample Code Transfer</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> $().ready(function() { $("#userid").change( function() { var user = $(this).val() $.get( "", {"ajax":1, "userid":user }, function(resp) { $("#credits").html(resp) }, "TEXT" ) }) }) </script> <style type="text/css"> label {display:inline-block; width: 160px; font-weight: 600;} </style> </head> <body> <form method='post'> <fieldset> <legend>Codes Transfer</legend> <label>From user</label><input type="text" name="userid" id="userid" value="<?=$userid?>" size="5"><br> <label>Credits to transfer</label><select name="credits" id="credits"><?=cr_options($db, $userid, $cr)?></select><br><br> <label>To user</label><input type="text" name="subid" id="subid" value="<?=$subid?>" size="5"><br> <label> </label><input type="submit" name="btnSub" value="Transfer"> </fieldset> </form> <br> <br> <?=$before?> <?=$confirm?> <?=$after?> </body> </html>
-
What's wrong with one form and let the user select from a choice of 4 options?
-
6 minutes ago, StevenOliver said:
There's nothing on the 'net like this
There is an example of GROUP BY and GROUP_CONCAT in the SQL tutorial in my sig
-
2 minutes ago, StevenOliver said:
I don't know how you know this stuff.
It's all in the manual
Regex breaks down when it encounters a º sign or an &
in PHP Coding Help
Posted
It looks like your output is a single string ...
… (a json-encoded array) which is why you get a single <li> item.
However, you should get the required result if you ...