PHP use array or extract to variables? - php

This is a question more of style than function. At the moment I use the following code to produce an array of values that have gone through various regex's in a function.
However this means having to reference the final array, which when adding lots of values to an SQL query can start to look quite messy compared to straight variables.
I could extract the array to variables after the function is called but am wondering if there is some way to do this from within the function and not run into problems with scope or should I actually avoid using straight variables and stick with the array?
<?php
function formData($form_vars)
{
$regex_array = array(
'alpha_num' => "/[^a-zA-Z0-9[:space:][:blank:]]/",
'basic' => "/[^a-zA-Z0-9[:space:][:blank:],.\\'()&-]/"
);
foreach ($form_vars as $key => $var) {
$regex = $regex_array[$var];
$val = preg_replace($regex, '', $_REQUEST[$key]);
$vars[$key] = $val;
}
return $vars;
}
$vars = array(
'address_one' => "basic",
'address_two' => "basic",
'address_three' => "basic",
'postal' => "alpha_num"
);
$vars = formData($vars);
echo $vars['address_one'];
?>

To be point on your question and not diverge on other things I'd like to comment on:
$regex_array (which I'd call $softTypeFilters) and $vars (which I'd call $fieldSoftTypes) can be expternalized into a configuration file right now. So I'd stick with this and not use your other suggestion. You might loose this functionality (configurability) which is very powerful. And the code is still easy to read.

You don't need to extract $vars and can use it to build your query easier (with a function build_query($var) for example, with an other loop)
EDIT detailled answer: I think about something like this:
<?php
function formData($vars, $alias)
{
foreach($_POST as $k => $v)
{
// skip unknown fields
if (!isset($vars[$k]))
continue;
// deal with input names != field name
$field_name = isset($form_alias[$k])?$form_alias[$k]:$k;
$vars[$key] = preg_replace($regex, '', $_REQUEST[$key]);
if (function_exists('preprocess_'.$key))
$vars[$key] = call_user_func('preprocess_'.$key, $vars[$key]);
}
return $vars;
}
function buildQuery($vars)
{
$sql = '';
// use a query builder, PDO prepared statements or anything
foreach($vars as $field => $value)
{
// ...
}
return $sql;
}
$vars = array(
'address_one' => "basic",
'address_two' => "basic",
'address_three' => "basic",
'postal' => "alpha_num",
);
$form_alias = array(
'address1' => "address_one",
'address2' => "address_two",
'address3' => "address_three",
);
$vars = formData($vars, $form_alias);
$query = buildQuery($vars);

Related

PHP - Put variables with a prefix into array

Is there any way of putting variables into an array? I'm not really sure how else to explain it.
I'm developing a website that works with a game server.
The game exports a file which contains variables such as:
$RL_PlayerScore_CurrentTrail_14911 = "lasergold";
$RL_PlayerScore_HasTrail_14911_LaserGold = 1;
$RL_PlayerScore_Money_14911 = 2148;
I'd like to convert these into an array like
$data = array(
'CurrentTrail_14911' => 'lasergold'
'HasTrail_14911_LaserGold' => '1'
'Money_14911' => '2184'
);
Is there any way I could do this?
Thanks in advance
Include file in scope and then get array of defined vars, excluding globals you don't need.
include('name-of-your-file.php');
$data = get_defined_vars();
$data = array_diff_key($data, array(
'GLOBALS' => 1,
'_FILES' => 1,
'_COOKIE' => 1,
'_POST' => 1,
'_GET' => 1,
'_SERVER' => 1,
'_ENV' => 1,
'ignore' => 1 )
);
You can return an array with all your declared variables, and loop through them cutting off the desired piece of text. You could do something like this:
<?php
//echo your generated file here;
$generatedVars = get_defined_vars();
$convertedArray = array();
foreach($generatedVars as $key=>$var)
{
$key = str_replace("RL_PlayerScore_","",$key);
$convertedArray[$key] = $var;
}
If all game variables are going to begin with 'RL_PlayerScore_', you could use something like that :
$vars = [];
foreach($GLOBALS as $var => $value) {
if(strpos($var, 'RL_PlayerScore_') === 0) {
$vars[$var] = $value;
}
}
$vars will be filled by all your variables.
See #Dagon comment also.

PHP: Updating an associative array though a class function?

I want to be able to update an associative array within an object based on function input, but I'm at a loss for how to do this. Here's my problem. Let's say there's this data container in my object:
private $vars = Array
(
['user_info'] = Array
(
['name'] => 'John Doe'
['id'] => 46338945
['email'] => 'johndoe#example.com'
['age'] => 35
)
['session_info'] = Array
(
['name'] => 'session_name'
['id'] => 'mGh44Jf0nfNNFmm'
)
)
and I have a public function update to change these values:
public function update($keys, $changeValueTo) {
if (!is_array($keys)) {
$keys = array($keys);
}
nowWhat();
}
Ultimately, I just want to be able to convert something like this
array('user_info', 'name')
into this:
$this->vars['user_info']['name']
so I can set it equal to the $equalTo parameter.
This usually wouldn't be a problem, but in this scenario, I don't know the schema of the $vars array so I can't write a foreach statement based on a fixed number of keys. I also can't just make $vars public, because the function needs to do something within the object every time something is changed.
I'm worried that this is a recursive scenario that will involve resorting to eval(). What would you recommend?
It is not hard to do it. You need passing variable by reference and a loop to achieve. No need eval().
$var = array(
"user_info" => array(
"name" => "Visal"
)
);
function update(&$var, $key, $value) {
// assuming the $key is an array
$t = &$var;
foreach ($key as $v) {
$t = &$t[$v];
}
$t = $value;
}
update($var, array("user_info", "name"), "Hello World");
var_dump($var);

PHP - good practice reading POST variables

I am thinking of a good practice to read the client submitted POST data.
For example if I have a post variable that should have the following structure:
array(
[0] => array(
['test'] => array(1, 2, 3),
['test2'] => "string"
),
[1] => array(
['test'] => array(),
['test2'] => "string2"
),
)
Where the indices 'test' and 'test2' should always be present but their values may be empty (array() and "");
The functions that handle the POST data are expecting the correct format, so I have to make sure that the data has not been manipulated.
I could do the following:
$result = array();
if(isset($_POST['myVar']) && is_array($_POST['myVar'])) {
foreach($_POST['myVar'] as $array) {
$new = array('test' => array(), 'test2' = "");
if(isset($array['test']) && is_array($array['test'])) {
foreach($array['test'] as $expectedInt) {
$new['test'][] = (int)$expectedInt;
}
}
if(isset($array['test2']) && is_string($array['test2']))
$new['test2'] = $array['test2'];
}
$result[] = $new;
}
I think you get the idea what I mean. I wonder if there is a better practice of reading the POST data into the expected format.
I usually do this to assure I have default indices:
$par = $_POST;
$par += [
'key' => 'default',
'other' => 'default',
]
If $par doesn't contain those keys, they are set.
In your case, your could do this:
$ready = [];
foreach($_POST as $k => $v){
$v += [
'test' => [],
'test2' => "string2",
];
// Validate if needed
$v['test'] = (array)$v['test'];
$v['test2'] = (string)$v['test2'];
$ready[$k] = $v;
}
Later you can be sure, that $ready will contain values with test and test2 keys.
This is very useful in functions, where you replace a lot of arguments with one parameter array, and then later set default values,

PHP Api - Results/Array question

I have been looking around for PHP tutorials and I found a very detailed one that have been useful to me.
But now, I have a question. The results showed by the API are stored into a $results array. This is the code (for instance):
$fetch = mysql_fetch_row($go);
$return = Array($fetch[0],$fetch[1]);
$results = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
My question is.. I want to display the last 10 news.. how do I do this? On normal PHP / mySQL it can be done as:
while($var = mysql_fetch_array($table)) {
echo "do something"
}
How can I make it so the $results can print multiple results?
I have tried like:
while($var = mysql_fetch_array($table)) {
$results = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
}
But this only shows me one result. If I change the $results .= Array(...) it gives error.
What can I do?
Thanks!
Edit
My function to read it doesn't read when I put it the suggested way:
function write(XMLWriter $xml, $data){
foreach($data as $key => $value){
if(is_array($value)){
$xml->startElement($key);
write($xml, $value);
$xml->endElement();
continue;
}
$xml->writeElement($key, $value);
}
}
write($xml, $results);
$results[] = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
That should do it.
If you are familiar with arrays, this is the equivalent of an array_push();
array_push() treats array as a stack, and pushes the passed variables onto the end of array. The length of array increases by the number of variables pushed. Has the same effect as:
<?php
$array[] = $var;
?>
Use [] to add elements to an array:
$results = array();
while($var = mysql_fetch_array($table)) {
$results[] = Array(
'news' => Array (
'id' => $var[0],
'title' => $var[1]
));
}
}
You can then loop through the $results array. It's not an optimal structure but you should get the hang of it with this.

How to combine the keys and values of an array in PHP

Say I have an array of key/value pairs in PHP:
array( 'foo' => 'bar', 'baz' => 'qux' );
What's the simplest way to transform this to an array that looks like the following?
array( 'foo=bar', 'baz=qux' );
i.e.
array( 0 => 'foo=bar', 1 => 'baz=qux');
In perl, I'd do something like
map { "$_=$hash{$_}" } keys %hash
Is there something like this in the panoply of array functions in PHP? Nothing I looked at seemed like a convenient solution.
Another option for this problem: On PHP 5.3+ you can use array_map() with a closure (you can do this with PHP prior 5.2, but the code will get quite messy!).
"Oh, but on array_map()you only get the value!".
Yeah, that's right, but we can map more than one array! :)
$arr = array( 'foo' => 'bar', 'baz' => 'qux' );
$result = array_map(function($k, $v){
return "$k=$v";
}, array_keys($arr), array_values($arr));
function parameterize_array($array) {
$out = array();
foreach($array as $key => $value)
$out[] = "$key=$value";
return $out;
}
A "curious" way to do it =P
// using '::' as a temporary separator, could be anything provided
// it doesn't exist elsewhere in the array
$test = split( '::', urldecode( http_build_query( $test, '', '::' ) ) );
chaos' answer is nice and straightfoward. For a more general sense though, you might have missed the array_map() function which is what you alluded to with your map { "$_=$hash{$_}" } keys %hash example.

Categories