How to set properties of an object dynamically, from a variable name? - php

I'm trying to populate a template with variables from a database. The data looks as follows:
id field content
1 title New Website
1 heading Welcome!
1 intro This is a new website I have made, feel free to have a look around
2 title About
2 heading Read all about it!
What I need to do with that data is set properties of a $template object according to the field column and set said values to what's in the content column; e.g. for id = 1
$template->title = 'New Website';
$template->heading = 'Welcome!';
$template->intro = 'This is a new websi...';
I have the data in an array and I can easily loop over it but I just can't figure out how to get the properties to be the names of another variable. I've tried the variable variables approach but to no avail. Does that work with object properties?
Here's what I've got so far:
foreach($data as $field)
{
$field_name = $field['field'];
$template->$$field_name = $field['content'];
}
I've also tried using $template->${$field_name} and $template->$$field_name but so far no luck!

$template->{$field_name}

You're getting ahead of yourself.
try:
$template->$field_name;
Why does this work?
$foo = 'bar';
$object->bar = 1;
if ($object->$foo == $object->bar){
echo "Wow!";
}

use
$template->{$field_name} = $field['content'];
or simply
$template->$field_name = $field['content'];

Related

Creating a variable if a form input field contains data using PHP

I am working on a project for one of my professors and have added a way to dynamically add input fields as shown here:
Before creating this form I had 6 sets of input fields and was posting them using the following code in PHP:
$author1 = $_POST['author1_name'];
$author1uni = $_POST['author1_university'];
$author2 = $_POST['author2_name'];
$author2uni = $_POST['author2_university'];
$author3 = $_POST['author3_name'];
$author3uni = $_POST['author3_university'];
$author4 = $_POST['author4_name'];
$author4uni = $_POST['author4_university'];
$author5 = $_POST['author5_name'];
$author5uni = $_POST['author5_university'];
$author6 = $_POST['author6_name'];
$author6uni = $_POST['author6_university'];
I'd like to set these variables if they exists by doing something like :
$num = 1;
if (!empty($_POST['author' . $num]){
$author . $num = $_POST['author' . $num];
$num++;
}
in order to post the variables. I read that this is called variable variables and that it was bad practice. What would be the best method? I'm new to programming so I apologize if this question is dumb or not right for Stack Overflow but I've spent hours on this only to find out it was bad practice and don't want to make the same mistake twice. Thanks in advance for any help you can offer.
use arrays as names for input in your view like this
name="author_name[]"
name="author_university[]"
in php
foreach($_POST['author_name'] as $key => $val) {
echo $val."====>".$_POST["author_university"][$key];
//will echo corresponding author name and university.
}
For your reference, use isset() but works fine without that as well.
you can have like below code multiple times:
<input name="author[]" type="text"/>
<input name="uni[]" type="text" />
and after posting
$_POST['author'];
$_POST['uni'];
this will contain all fields value, loop through it like this:
foreach($_POST['author'] as $key => $val) {
echo $val." and ".$_POST["uni"][$key];
}

Using Simple HTML DOM to extract an 'a' URL

I have this code for scraping team names from a table
$url = 'http://fantasy.premierleague.com/my-leagues/303/standings/';
$html = #file_get_html($url);
//Cut out the table
$FullTable = $html->find('table[class=ismStandingsTable]',0);
//get the text from the 3rd cell in the row
$teamname = $FullTable->find('td',2)->innertext;
echo $teamname;
This much works.. and gives this output....
Why Always Me?
But when I add these lines..
$teamdetails = $teamname->find('a')->href;
echo $teamdetails;
I get completely blank output.
Any idea why? I am trying to get the /entry/110291/event-history/33/ as one variable, and the Why Always Me? as another.
Instead do this:
$tdhtml = DOMDocument::loadHTML($teamdetails);
$link = $tdhtml->getElementsByTagName('a');
$url = $link->item(0)->attributes->getNamedItem('href')->nodeValue;
$teamdetails = $teamname->find('a')->href;
^^^^^^^^^---- never defined in your code
I also fail to see how your "works" code could possibly work. You don't define $teamname in there either, so all you'd never get is the output of a null/undefined variable, which is...no output all.
Marc B is right, I get that you don't have to initialize a variable, but he is saying you are trying to access a property of said variable:
$teamdetails = $teamname->find('a')->href;
^^^^^^^^^---- never defined in your code
This is essentially:
$teamname = null;
$teamname->find('a')->href;
The problem in your example is that $teamname is a string and you're treating it like a simple_html_dom_node

PHP Function and variables stored in a string in a database

I need to store data within a database, when I get the data from the database I need functions and variables in the string to be worked out as such.
Example
$str = "<p>Dear {$this->name},</p>"
I then store this in the database, and when I retrieve the string and run it through
eval("\$detail= \"$detail\";");
then the variable gets populated with the name. This is exactly what I needed and works fine.
The problem is I want to run a function with this variable as the parameter.
example. I would like to ucwords the variable.
I have tried:
$str = "<p>Dear {ucwords($this->name)},</p>" //just echoed {ucword(->name)},
$str = "<p>Dear {ucwords($this->name)},</p>" //Fatal error: Function name must be a string,
Am I going in the right direction?
Is this at all possible?
You don't need to keep PHP code in database. This is a bad practice and also can lead to security vulnerabilities.
Instead store in database string like this:
<p>Dear [name],</p>
And when you retrieve it you can just do:
$stringFromDb = str_replace("[name]", $this->name, $stringFromDb);
or
$stringFromDb = str_replace("[name]", ucwords($this->name), $stringFromDb);
Other common approach is to use sprintf. So you need to store in database string with %s as placeholders for values.
Example:
<p>Dear %s,</p>
and replace with
$stringFromDb = sprintf($stringFromDb, ucwords($this->name));
What you seem to be looking for is a simple templating language.
It's been a long while since I've written PHP (and I suddenly remember why...), but here's something I whipped up.
It should support both objects ($a->name) and arrays ($a["name"]) as input objects.
You can add new filters (name -> function name mapping) in $valid_filters.
$valid_filters = array("title" => "ucfirst", "upper" => "strtoupper");
function _apply_template_helper($match) {
global $_apply_template_data, $valid_filters;
$var = $match[1];
$filter = $valid_filters[trim($match[2], ':')];
$value = is_array($_apply_template_data) ? $_apply_template_data[$var] : $_apply_template_data->$var;
if($filter && !empty($value)) $value = call_user_func($filter, $value);
return !empty($value) ? $value : $match[0];
}
function apply_template($template, $data) {
global $_apply_template_data;
$_apply_template_data = $data;
$result = preg_replace_callback('/\{\{(.+?)(:.+?)?\}\}/', "_apply_template_helper", $template);
$_apply_template_data = null;
return $result;
}
How to use it:
$template = "Hello {{name:title}}, you have been selected to win {{amount}}, {{salutation:upper}}";
echo apply_template($template, array("name"=>"john", "amount" => '$500,000', "salutation" => "congratulations"));
The result:
Hello John, you have been selected to win $500,000, CONGRATULATIONS
I have found the following works,
If i contain the function within the class itself then it can be called using the following code
<p>Dear {\$this->properCase(\$this->rl_account->name)},</p>
But i would like to be able to do this now without having the database have the code as Alex Amiryan mentions earlier.

Build a variable name in PHP out of two variables

Depending on the current page, I would like to change the css of the chosen menu module and make others different, etc. All that while building dynamically the page before loading.
My problem is that I have a serie of variables going by this structure :
$css_(NAME_OF_MODULE)
To know what variable must be set , I have another variable I received in parameters of this functions, called
$chosen_menu
Say $chosen_Menu = "C1", I would like to add content to $css_C1. Thus, what I want is to create a variable name out of 2 variables, named $css_C1
I have tried :
${$css_.$chosen_menu} = "value";
But it doesnt seem to work. Any clue ?
That probably won't just work. PHP supports full indirection though, so something like this will work.
$varName = $css."_".$chosen_menu;
$$varName = "value";
If not, it will probably be attempting to interpret $css_ as a variable name in your second code sample, so just change that to $css."_".$chosen_menu.
$nr = 1;
${'name' . $nr} = 20 ;
var_dump($name1);
Check out http://php.net/manual/en/language.variables.php
You should be able to use:
$menu = $css . '_' .$chosen_menu;
$$menu = 'some value';
or
${$menu} = 'some value';
I'm not sure if I get you right, but how about this:
${$css."_".$chosen_menu} = "value";

how to get value and set value of cck custom field

I know it might be a silly question to ask, but I have a field say a and b, now how to get the value and set the value for a and b.
Right now my code is like this..
$n = node_load($node->id);
$n->title;
I am getting the node title, I want to know how to get and set the value for a and b please, and if i set the value of a and b will itt be saved using
node_save($n);
??
It depends a bit which version you're using and on the particular field types you're using, but something like this:
// Drupal 6
$n = node_load($node->id);
$n->title = 'A title';
$n->field_my_field_a[0]['value'] = 'A value';
$n->field_my_field_b[0]['value'] = 'B value';
node_save($n);
// Drupal 7
$n = node_load($node->id);
$n->title = 'A title';
$n->field_my_field_a[LANGUAGE_NONE][0]['value'] = 'A value';
$n->field_my_field_b[LANGUAGE_NONE][0]['value'] = 'B value';
node_save($n);
In both cases the field data will be saved along with the node when you call node_save().
It's worth noting that the 0 index in both cases refers to the first item in a field. If a field has multiple values you can just keep adding to the array. The value key might need to change depending on the type of data that the field holds (for example a filefield will hold the fid (file id) of the file it holds so adjust accordingly.
Also LANGUAGE_NONE might need to be replaced by the required language code if you're using the Drupal 7 version.
Your question is a little confusing because you never explain what a and be are. But to access a cck field generally looks like this:
$node = node_load($nid);
$field_value = $node->field_name[0]['value'];
If it's a multiple select have values in offsets past zero. You can set the value using that same method:
$node = node_load($nid);
$node->field_name[0]['value'] = $field_value;
node_save($node);

Categories