Store values in PHP - php

I have an object that has a single comment on it and then that object has subobjects that each can have a comment on it. As it is today I have a single variable to store the comment on the whole object and a list to store the comments for the objects subobjects.
public $TestResultComments = array();
public $Comment;
Now I not only want to store the plain text of a comment but also store the username of that person that has wrote it and the timestamp. So instead of the single variable $Comment I now want to store three. What is the best way to store this, into an array or is there something similar as in Haskell where there are Tuples?
$comment = odbc_result($result, "comment");
$userName = odbc_result($result, "username");
$timeStamp = odbc_result($result, "timestamp");
$testResult->Comment = $comment;//This is what I do today, but I also want to include $userName and timestamp here
The second part is where I store the comments for the subobjects.
for ($i = 1; $i <= $no_results; $i++) {
odbc_fetch_row($result, $i);
$type = trim(odbc_result($result, "result"));
$testResult->TestResultComments[$type] = trim(odbc_result($result, "comment"));//Here I aswell want to store "comment","username" and "timestamp" as they are called in the database table and not only "comment" as I currently do.
}
As you can see in the second example I have a keyvalue "result" to get the comment. Here I also want to get the values ("comment","username","timestamp") instead of a single value as today.
Thanks in advance.

Seems like a nice situation to use the stdClass. stdClass allows you to dynamically declare fields for an object. You have an array of these, with say result as the key.
Example
$allValues = array();
// Create the values.
$values = new stdClass();
$values->comment = $comment;
$values->username = $username;
$values->timestamp = $timestamp;
$allValues[$result] = $values;
This gives you a direct mapping from a $result to several values, in a clean and OOP way. In the future, assuming you've created $result, you can say..
$values = $allValues[$result];
echo "The username is ". $values->username;
I really like using it because it makes your code super clean and OOP in syntax. For loosely typed languages like PHP, readability can sometimes be lost so it's important you maintain practises like this to keep things easy to understand.

Related

PHP: How to store dynamic variables within session variable?

Here is what I'm trying to do:
$username = 'john';
$_SESSION['data'] = "Hello ".$username;
$username = 'mike';
$new = $_SESSION['data']; // trying make it like: $new = "Hello ".$username;
echo $new // should output: "Hello Mike"
I'm trying to save a phrase with a dynamic variable into a $_SESSION variable, so the phrase can later be change on a different page depending on the dynamic variable.
Is this possible, and how can it be done?
You could use string formatting for that. Take a look:
$username = 'John'; // not really needed for this test
$_SESSION['data'] = "Hello %s";
$username = 'Mike';
$text = sprintf($_SESSION['data'], $username);
echo $text
Output:
Hello mike
See the code in action here.
It will not work the way you have it written, because the value you have stored in the session is a completely new value made using the value of the $username variable. As soon as it has been created, the value in the session is not associated with the $username variable whatsoever.
You can store the name and the phrase in the session separately, so they can be modified independently, and then combine them together later at the time you need to use them together.
For the specific case in your comment, storing the SQL string for a prepared statement with placeholders should work.
$_SESSION['statement'] = "SELECT some_columns FROM some_table LIMIT ?, ?";
$_SESSION['limit'] = $limit;
$_SESSION['offset'] = $offset;
You can't store the prepared statement itself, but you can store the SQL string, and then prepare and execute it in subsequent pages.
$stmt = $pdo->prepare($_SESSION['statement']);
$stmt->execute([ $_SESSION['limit'], $_SESSION['offset'] ]);
Just remember when you are ready to bind values to it on your next page before executing it that you need to specify that they should be bound as integers or disable emulated prepared statements.
If you want to add new element in the session array then you can push new element in the session array as follows:
array_push($_SESSION['data'],$element)
You could do something like this:
$username = 'john';
$_SESSION['data'] = 'echo "Hello $username";';
$username = 'mike';
eval($_SESSION['data']);
But I don't know why you'd want to, there are millions of ways you could achieve the results you want, an approach like this probably isn't the best.

Intersection with redbeanphp

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.

Pulling settings from MySQL using Object-Orientated PHP

Ok, so I am slowly migrating from Procedural to OOP, and I'm finding it all pretty straight forward apart from one thing.
I used to use this method for pulling my settings data from a simple two-column settings table comprising of a row for each setting, defined with 'setting' and 'value' fields:
$query = mysql_query("SELECT * FROM `settings`");
while ($current_setting = mysql_fetch_array($query)) {
$setting[$current_setting['setting']] = $current_setting['value'];
}
As you can see, I manipulated it so that I could simply use $setting['any_setting_name'] to display the corresponding 'value' within that setting's row. I'm not sure if this is a silly way of doing things but no matter, I'm moving on anyway..
However, since moving to object orientated PHP, I don't really know how to do something similar..
$query = $mysqli->query("SELECT * FROM `settings`");
while ($current_setting = $query->fetch_object()) {
echo $current_setting->setting; // echo's each setting name
echo $current_setting->value; // echo's each setting value
}
As you can see, I'm perfectly able to retrieve the data, but what I want is to be able to use it later on in the form of: $setting->setting_name; which will echo the VALUE from the row where setting is equal to 'setting_name'..
So basically if I have a row in my settings table where setting is 'site_url' and value is 'http://example.com/', I want $setting->site_url; to contain 'http://example.com/'.. Or something to the same effect..
Can anyone help me out here? I'm at a brick-wall right now.. Probably something really stupid I'm overlooking..
Since you are working with a resource it has a pointer. Once you get to the end you can't use it anymore. I think you can reset it but why not mix the new with the old?
I don't think you're going to have too much overhead, any that matters anyway, to do something like this:
$settings = array();
$query = $mysqli->query("SELECT * FROM `settings`");
while ($current_setting = $query->fetch_object()) {
$settings[$current_setting->setting] = $current_setting->value;
}
Now you can use $settings as much as you want.
UPDATE
Haven't tested this or used it but are you looking to do something like this? Consider the following pseudo code and may not actually work.
$settings = new stdClass();
$query = $mysqli->query("SELECT * FROM `settings`");
while ($current_setting = $query->fetch_object()) {
$settings->{$current_setting->setting} = $current_setting->value;
}

Is it best to make fewer calls to the database and output the results in an array?

I'm trying to create a more succinct way to make hundreds of db calls. Instead of writing the whole query out every time I wanted to output a single field, I tried to port the code into a class that did all the query work. This is the class I have so far:
class Listing {
/* Connect to the database */
private $mysql;
function __construct() {
$this->mysql = new mysqli(DB_LOC, DB_USER, DB_PASS, DB) or die('Could not connect');
}
function getListingInfo($l_id = "", $category = "", $subcategory = "", $username = "", $status = "active") {
$condition = "`status` = '$status'";
if (!empty($l_id)) $condition .= "AND `L_ID` = '$l_id'";
if (!empty($category)) $condition .= "AND `category` = '$category'";
if (!empty($subcategory)) $condition .= "AND `subcategory` = '$subcategory'";
if (!empty($username)) $condition .= "AND `username` = '$username'";
$result = $this->mysql->query("SELECT * FROM listing WHERE $condition") or die('Error fetching values');
$info = $result->fetch_object() or die('Could not create object');
return $info;
}
}
This makes it easy to access any info I want from a single row.
$listing = new Listing;
echo $listing->getListingInfo('','Books')->title;
This outputs the title of the first listing in the category "Books". But if I want to output the price of that listing, I have to make another call to getListingInfo(). This makes another query on the db and again returns only the first row.
This is much more succinct than writing the entire query each time, but I feel like I may be calling the db too often. Is there a better way to output the data from my class and still be succinct in accessing it (maybe outputting all the rows to an array and returning the array)? If yes, How?
Do you actually have a performance issue?
If your current setup works and doesn't suffer from performance issues, I wouldn't touch it.
This sort of DB access abstraction will likely become a maintenance issue and probably won't help performance.
Also, you're susceptible to SQL injection.
You should be able to store the whole object from the query into a variable and then access the single values from that object:
$object = $listing->getListingInfo('','Books');
$title = $object->title;
$price= $object->price;
But you can also use fetch_assoc() and return the whole assiciative array:
$array = $listing->getListingInfo('','Books');
$title = $object['title'];
$price= $object['price'];
This will give you the same results and also with only one query to the DB.
EDIT: If the getListingInfo() is the only function you should think of the following:
rename the function to prepareListingInfo() and within the function only prepare the query and store it in a class variable.
add a getNextListingInfo() function, which will return an object or associative array with the next row.
Using this new function, you can get every row that matches your query.
Either cache the result in an internal var
Or Comment it with a warning and explain to function users to copy the result in an var instead of calling it again and again with the same params
Yes, that would be calling the db too often.
A couple of solutions
1) put the listing info in a variable
2) cache the results in a hashmap or dictionary (be careful for memory leaks)

An example of arrays being used in web development

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"];
}

Categories