I have an array $mycontacts of beans of type $contact
where:
$contact->id = $x
$contact->name = $y
$contact->email= $z
I want to check the $mycontacts array against a second array $contacted also of type $contact.
I want to perform $mycontacts - $contacted to yield a subset which I have not contacted based on the email parameter. Now i could do something like
foreach ($mycontacts as $mycontact) {
loop through $contacted and compare $contacted->email to $mycontact->email
}
Is there a better way to do this either with php, redbean or mysql?
$sql = 'SELECT *
FROM contact
WHERE id NOT IN (SELECT mycontact.id
FROM contact AS mycontact
WHERE 1/* your condition*/)';
$rows = R::getAll( $sql );
$contactsMinusMyContacts = R::convertToBeans( 'contact', $rows );
This code should be the best performing, as it runs nearly entirely on the database, which is the best place to work with sets of data. It first selects all contacts, then subtracts "my contacts" and returns the result. RedBean then converts it back to beans.
Related
Is there a way I can echo an array of value in this format[200,135,667,333,526,996,564,123,890,464,655] I have my PHP code as below:
$sql_sum_up = "SELECT * FROM `payment`";
$result_sum_up = mysqli_query($conn,$sql_sum_up);
$count_sum_up = mysqli_num_rows($result_sum_up);
while($row_sum_up = mysqli_fetch_array($result_sum_up,MYSQLI_ASSOC)){
$price = $row_sum_up['price'];
}
I want when I echo $price it should come in this format [200,135,667,333,526,996,564,123,890,464,655]
Start of by indenting your code correctly. There's almost always a function for auto-formatting in most editors, such as Visual Studio Code, NetBeans, etc. Or use an online tool to do it.
Correct your SQL query since there's no point getting all values if you just read the price value and you are ordering without mentionning the field name:
SELECT `price` FROM `payment` ORDER BY `field_name` DESC
Create an array variable which you will fill with the prices:
$prices = [];
In your loop reading the database values, fill the array:
$prices[] = $row_sum_up['price'];
Alternatively, you could also fetch all values instead of looping. By the way, it's best to use PHP's PDO abstraction layer instead of mysqli_() functions.
After the loop, export it to JSON:
print json_encode($prices);
first of all, as someone already mentioned in the comments you have an error in your SQL synthax. The correct ORDER BY synthax is "ORDER BY [field-name] DESC"
You could achieve what you want in different ways.
First of all you want to create an array that contains all prices:
$sql_sum_up = "SELECT * FROM `payment`";
$result_sum_up = mysqli_query($conn,$sql_sum_up);
$count_sum_up = mysqli_num_rows($result_sum_up);
$prices = []; //Create the prices array
while($row_sum_up = mysqli_fetch_array($result_sum_up,MYSQLI_ASSOC)){
$prices[] = $row_sum_up['price']; //This pushes every price into the array
}
Make use of join/implode - PHP.net join function
echo '['.join(',',$prices).']';
You could use json_encode function PHP.net json_encode function
echo json_encode($prices);
This question already has answers here:
Is there a way to fetch associative array grouped by the values of a specified column with PDO?
(8 answers)
Closed 1 year ago.
I want to send the overdue tasks that are assigned to a specific employee as an email summary. It is possible that multiple todos are assigned to the same employee. So multiple todos can be assigned to the same employee AND are overdue. That's where the problem starts...
So what I did, is grabbing all the overdue tasks from the database and then I grabbed the assigned employees to the tasks. I created an array that consists of the todoID, the employeeID and the employeeEmail. Now, is there a better way to do this and if not, how can I group the rows by email address?
The end result should be an array that shows every overdue todo that's assigned to one employee.
// Get all Todos that are not archived
$sql = "SELECT * FROM todo WHERE archiv = 0";
$abfrage = $db->prepare($sql);
$abfrage->execute();
$overdue_array = array();
// Now we get everything that's overdue from the Database
while ($row = $abfrage->fetch()) {
if ($row["status"] !== 3) {
if ($row["archiv"] !== 1) {
if ($row["durchfuehrung"]) {
if (strtotime($row["durchfuehrung"]) < strtotime(date("Y-m-d"))) {
// Here we now get the email from the assiged employee to the todo
$sql2 = "SELECT email FROM mitarbeiter WHERE mitarbeiterID = :mitarbeiterFID";
$abfrage2 = $db->prepare($sql2);
$abfrage2->bindParam("mitarbeiterFID", $row["mitarbeiterFID"]);
$abfrage2->execute();
while ($row2 = $abfrage2->fetch()) {
$overdue_array[] = array("todoID" => $row["todoID"], "mitarbeiterID" => $row["mitarbeiterFID"], "mitarbeiterEmail" => $row2["email"]);
}
}
}
}
}
The result is the following:
Let's pretty up your scripting with some best practices...
only add columns to your SELECT clause when you have a use for them
enjoy PDO's very handy fetching modes -- FETCH_GROUP is perfect for your case.
always endeavor to minimize trips to the database
always endeavor to minimize the number of loops that you use.
Recommended code (yes, it is just that simple):
$sql = "SELECT email, todoID, mitarbeiterFID
FROM todo
JOIN mitarbeiter ON mitarbeiterID = mitarbeiterFID
WHERE archiv = 0
AND status != 3
AND durchfuehrung < CURRENT_DATE";
foreach ($db->query($sql)->fetchAll(PDO::FETCH_GROUP) as $email => $rows) {
sendSummary($email, $rows, $company, $db);
}
For the record, I don't know where $company comes from.
You could strongly improve your request with a JOIN (as said #mickmackusa) and even structure your response with PDO Fetch Statements (like PDO FETCH_GROUP or PDO FETCH ASSOC). You could directly get the result you want with one (bigger but better) request.
Nevertheless, if you want to simply sort your array with PHP, the use of foreach can do the job.
foreach ($array as $todo) {
if (!isset($newArray[$todo["mitarbeiterEmail"]])) {
// Here we create a new array with the email as a key and put the two first key-values in it with array_slice
$newArray[$todo["mitarbeiterEmail"]] = [array_slice($todo, 0, 2)];
} else {
// Here we push another todo if the email is already declared as a key
array_push($newArray[$todo["mitarbeiterEmail"]], array_slice($todo, 0, 2));
}
}
// Check your new array
print_r($newArray);
You could also avoid foreach by combining array_multisort to sort by emails then array_reduce to remove duplicate elements keeping associated data. Many solutions can be proposed.
Suppose I have 2 tables:
Applicants:
- id
- full_name
- address
Educations:
- id
- applicant_id
- institute
- address
After I did an inner join, I want to loop through the data on a template. But first I want to convert all educational records for an applicant into an array and attach it to the applicant record.
applicant_a:
- id
- full_name
- address
- educations: [ OBJECTS HERE ]
What's the way to do so? Can I do it on the database side via SQL? Or do I have to do it on PHP side?
This is a simple draft of how I would do it in your case.
I'm not saying this is the best or even the only way to do it.
This specific is not tested, though I used that logic often before.
Note, that this is only about the logic here.... but this should give you what you want!
$applicants = array();
$old_applicant_id=null;
while ($row=$db->fetch()) {
// new applicant
if($row['applicant_id']!=$old_applicant_id) {
// save the education to the old one - if there is one
if(isset($applicant)) {
$applicant['education'] = $educations;
$applicants[] = $applicant;
}
// then (and in first round)
$applicant = array();
$applicant['fullName'] = $row['fullName'];
// repeat for other values of applicant
$educations = array(); // initialize educations
$education = array();
$education['id'] = $row['edu_id'];
// repeat for institute, etc
$educations[] = $education;
} else {
// already existing applicant, so only add education
$education = array();
$education['id'] = $row['edu_id'];
// repeat for institute, etc
$educations[] = $education;
}
// set old applicant
$old_applicant_id = $row['applicant_id'];
}
// finally you have to save the last one to the array
$applicant['education'] = $educations;
$applicants[] = $applicant;
Another way would be to have two seperate queries and merge them in two loops.
This question of mine was related. I was asking about the spead of the two versions. Might be interesting.
MySQL does not return arrays, so this kind of thing is usually best done in client code (in this case PHP).
But if you are just going to concatenate the educations into a string of some sort you may want to look into the GROUP_CONCAT aggregate function.
The intention with the below code is to extract messages from a mysql table, and put each of them inside ONE array with {} around each output. Each output consists of various parameters as you can see, and is an array in itself.
What the code does is that each time the loop is processed, in the JSON array that this later is converted into, it wraps the output in []´s, hence it´s now a new array which is created.
What I get is:
[{"sender":"ll","message":"blah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"kk","message":"blahblah","timestamp":"2016-12-21 14:43:23","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"ll","message":"blahblahblah","timestamp":"2016-12-21 14:43:47","username":"","msgtype":"","threadid":"32629016712222016034323"}],[{"sender":"ll","message":"blahblahblahblah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"92337321312222016034304"},{"sender":"kk","message":"blahblahblahblahblah","timestamp":"2016-12-21 14:44:05","username":"","msgtype":"","threadid":"92337321312222016034304"}]]
And what I want is:
[{"sender":"ll","message":"blah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"kk","message":"blahblah","timestamp":"2016-12-21 14:43:23","username":"","msgtype":"","threadid":"32629016712222016034323"},{"sender":"ll","message":"blahblahblah","timestamp":"2016-12-21 14:43:47","username":"","msgtype":"","threadid":"32629016712222016034323"}],{"sender":"ll","message":"blahblahblahblah","timestamp":"2016-12-21 14:43:04","username":"","msgtype":"","threadid":"92337321312222016034304"},{"sender":"kk","message":"blahblahblahblahblah","timestamp":"2016-12-21 14:44:05","username":"","msgtype":"","threadid":"92337321312222016034304"}]
How do I proceed to get the right result here?
$data = array ();
foreach($threads as $threadid){
$sql = ("SELECT sender,message,timestamp,username,msgtype,threadid FROM Messages WHERE threadid = '$threadid' AND subject = '' AND timestamp > '$newtimestamp' ORDER BY timestamp");
$arrayOfObjects = $conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
$data[] = $$arrayOfObjects;
}
And FYI, $threadid is another array containing... threadids, and the loop correctly fetches these one by one, that´s not where the problem is.
Thanks in advance!!
You are doing O(N) database queries, consider doing just O(1) using an IN expression in your where clause. No need for a foreach loop and you'll get all your data in one array.
SELECT ... FROM Messages WHERE threadid IN (1, 2, 3, ...) AND ...
You might have to use a prepared statement for that.
I think you are searching for PDO::FETCH_OBJ.
You had FETCH_ASSOC, which will return an array of associative arrays.
FETCH_OBJwill return an array ob stdObjects.
Also you reassigned $array to itself when doing $array[] = $array;..
$data = array();
foreach($threads as $threadid){
$sql = ("SELECT sender,message,timestamp,username,msgtype,threadid FROM Messages WHERE threadid = '$threadid' AND subject = '' AND timestamp > '$newtimestamp' ORDER BY timestamp");
// here it is:
$arrayOfObjects = $conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
$data[] = $arrayOfObjects;
}
// now you can encode that as json and show it:
echo json_encode($data);
#akuhn
Well, I decided to give your suggestion one more try, and managed to do it in a none prepared way. I´m aware that this is supposed to be risky, but so far this project just needs to work, then have the php codes updated to safer versions, and then go live. It works, so thanks a bunch!
$sql = ("SELECT sender,message,timestamp,username,msgtype,threadid FROM Messages WHERE threadid IN ('" . implode("','",$threadid) . "') AND subject = '' AND timestamp > '$newtimestamp' ORDER BY timestamp");
$data = $conn->query($sql)->fetchAll(PDO::FETCH_OBJ);
I was talking to a person today who mentioned he used arrays when calling parameters or for other reasons when pulling data from the database etc.
Basically my question is: how would you use arrays in web development?
For example:
If you had a url like this (a social dating site)
http://www.example.com/page.php?sid=1&agefrom=30&ageto=40&sex=female&loccation=los angeles
How I would query the browse page (when showing a list of users) is
$id = mysql_real_escape_string($_GET['id']);
$agefrom = mysql_real_escape_string($_GET['agefrom']);
$ageto = mysql_real_escape_string($_GET['ageto']);
$sex = mysql_real_escape_string($_GET['sex']);
$location = mysql_real_escape_string($_GET['location']);
mysql_query("select from table where id = '$id' and agefrom='$agefrom' [.....the rest of the query]")
Can this be done with arrays? What if a location wasn't selected or the age wasn't entered? If i did the query it might fail.
I hope my question is more clear now.
Arrays make it easy to hold a set of values, or key => value pairs, inside a variable. It also makes it easy to iterate over a set of values.
foreach ($myarray as $key => $value)
{
// do something with this key and value
}
If you are passing a large number of values to a function, and this set of values could be thought of as a list or a lookup table, then you would use an array.
Please consult the PHP manual on arrays for more information.
Edit:
I think I see what you mean now. It can be helpful to sort of 'abstract' your database calls by creating a function that accepts values as an array. For example:
function editrecord($recordid, $values)
{
// SQL is generated by what is in $values, and then query is run
// remember to check keys for validity and escape values properly
}
That's an extreme simplication of course.
Arrays are an important feature of any language, they have O(1) (constant time) random access and can be used as a base data structure to make more complex types.
Specifically talking about PHP, the arrays are used VERY often, the language itself uses them for example to grab the GET and POST parameters.
To get data, you can also make use of arrays in PHP.
You can use mysql_fetch_assoc, this will retch a result row from the database as an associative array, each index of the array will represent a column of data of the current row:
//...
$sql = "SELECT id as userid, fullname, userstatus
FROM sometable
WHERE userstatus = 1";
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result)) {
// Here, the $row variable is an associative array.
echo $row["userid"];
echo $row["fullname"];
echo $row["userstatus"];
}