I'm just looking for a MORE eloquent way of defining an array of empty error strings for a mail form then this...
$err = array('NAME'=>'', 'EMAIL'=>'', 'ADDR'=>'', 'CS_LOC'=>'', 'ZIP'=>'','PHONE'=>'', 'COMMENTS'=>'', 'FILE'=> '');
Since I have to flush these occasionally anyway, certainly anytime the form posts, I've already set up a function like the below which I call as needed, like this.
function clearFormErrors(&$ary) { // fill error array with empty strings
$keys = array_keys($ary);
$filled = array_fill_keys($keys, '');
}
Not a big deal [EDIT]:, but since I'm going to call this anyway, it would be nice if there were some nice 'wishlist' way I could just define the array **KEYS when I declare it**, like this...
$err = array('NAME', 'EMAIL, 'ADDR', 'CS_LOC, 'ZIP,'PHONE', 'COMMENTS, 'FILE');
Of course the above does NOT have that desired effect. I'm just curious if there is some simple directive or method that I've missed in the PHP docs that would just let me define the keys (with or without some default type). I'm sure there is a more complicated function that could be created to build a new array using the keys (now values) from my above 'wishlist' array, but it sounds like it wouldn't make the code any shorter or more 'eloquent', right?
If you have array of keys, array_fill_keys is the most elegant way to "reset" the array. The other way that makes sense is array_map, but for your simple task it seems like a little overhead.
Related
There exists such:
$var1 = $var2 = "blabla";
but is there a way to set similar inside array? like:
array(
'key1'='key2' => "blabla",
...................
)
p.s. I dont need outside of array functions, like array_fill_keys or etc.. I want inside-array solution (if it exists).
You can set multiple array values of an array like this. Perhaps it even works without the first line.
$a = array();
$a['key1'] = $a['key2'] = 'blablabla';
Or initialize the desired keys using this awkward syntax:
$a = array_fill_keys(array('key1', 'key2'), 'blablabla');
Although the second one works, I wouldn't use it. Better to use a couple of characters extra or even separate lines than to write such a weird line which doesn't have much benefit apart from saving a tiny bit of code.
I think this is quite interesting!!! :).
What I've got?
In the application that I'm using on some level in some objects (doesn't really matter) I get an array, for example:
$array = array(
'argument_label' => 'value_label',
'argument_name' => 'value_name',
'argument_id' => 'value_id'
)
I don't have any impact on how and when this array is created. Next, I've got a method:
public function arrayArgument($array) {
$label = isset($array['argument_label']) ? $array['argument_label'] : 'default_label';
$name = isset($array['argument_name']) ? $array['argument_name'] : 'default_name';
$id = isset($array['argument_id']) ? $array['argument_id'] : 'default_id';
// Do something
return 'something';
}
I really hate it. There is no way of proper documentation for the method arguments (as PHPDocumentator work not so well with arrays), and those issets are driving me crazy. Additionally it is a nightmare for someone who will work with this code in the future, when I will already be a "retired nerd".
What I want?
I want to have a function like that:
public function notArrayArgument(
$id='default_id',
$label='default_label',
$name='default_name'
) {
// Do something
return 'something';
}
What I can do?
When I get array, I can change some code, and make my own method run. So I need some kind of solution to get from here:
$array = array(
'argument_label' => 'value_label',
'argument_name' => 'value_name',
'argument_id' => 'value_id'
)
To here:
notArrayArgument('value_id', 'value_label', 'value_name');
Or here:
notArrayArgument($array['argument_id'], $array['argument_label'], $array['argument_name']);
What are the problems?
This is not template like. The number of variables is always different, the names are always different, and sometimes some of them are passed, sometimes not.
It should work really fast...
Calling the method arguments in the right order. Array can be sorted, not sorted or random sorted, while the arguments inside method are always in the same order. The array should be reordered to match the method arguments order, and after that the method should be called.
What I came with?
I've got an idea using reflectionClass. I can check the names of method arguments, get them in order, reorder the array and try to call this method. But this is quite resource eating solution, as reflectionClass is not so fast I think.
Solution using extract? This would be great. But after extract, I need to use exact variables names in code. And I don't know them as every time they are different, and I need an universal approach.
NEW (thx to comment): call_user_func_array(). It is great, but it only works with indexed arrays, so this will be the last but not least step of the possible solution. As the order of arguments is still unknown...
Does this problem have a nice semantic, pragmatic solution?
I read my question once more, and I hope it is clear to understand. If not, please post a comment and I will do my best to describe the problem better.
Kudos for thinking about the maintainer, but I'd argue simplicity is just as important as nice semantics and pragmatism. Consider this: if you had to ask how to write such a pattern, what are the chances that it will be obvious to the reader? I'd much rather come across code where I can just think "Yep, that's clear" than "Oh cool that's a really intricate and clever way of setting array defaults".
With this in mind, it seems to me that an array is being used in a situation more suited to a class. You have an id, a label and a name, which surely represents an entity - exactly what classes are for! Classes make it easy to set defaults and provide PHPDoc on each of their properties. You could have a constructor that simply takes one of your existing arrays and array_merge()s it with an array of defaults. For the reverse conversion, conveniently, casting an object to an array in PHP results in an associative array of its properties.
Try to use classes as George Brighton mentioned.
If you can't for some legacy or library constraint, you will have to use reflection. Don't worry too much about the performance of reflection classes, a lot of frameworks use them to do the request routing.
You can use a function like:
function arrayArgument($object, $method, $array)
{
$arguments = [];
$reflectionMethod = new ReflectionMethod(get_class($object), $method);
foreach ($reflectionMethod->getParameters() as $parameter)
{
$arguments[] = isset($array[$parameter->name]) ? $array[$parameter->name] : $parameter->getDefaultValue();
}
call_user_func_array(array($object, $method), $arguments);
}
So you can do
$instance = new MyClass();
arrayArgument($instance, 'notArrayArgument', ['name' => 'myname']);
I have a query string. For example:
?filters=1,2,3,4
It gets turned into an array:
$filters = explode(',', $_GET['filters']);
You could push a new value on
$filters = array_push($filters, $new->filter);
Then turn it into the query string
http_build_query($filters);
Or, remove a value
$filters = array_diff($filters, [$new->filter]);
Then turn it into the query string
http_build_query($filters);
I'm looking for an elegant solution to remove the item if it already exists or to add the item if it does not exist. Alternative solutions are also welcome.
Thank you.
Hopefully I'm understanding you correctly "I'm looking for an elegant solution to remove the item if it already exists or to add the item if it does not exist.". Also, not sure if it is elegant but may spark other ideas:
$filters = in_array($new->filter, $filters) ?
array_diff($filters, [$new->filter]) :
array_merge($filters, [$new->filter]);
That's about as elegant as it gets, unless you want to use PHP's array notation "hack", e.g.
?filters[]=1&filters[]=2&filters[]=3&etc...
^^---
That'd save you the explode() stage and gives you the ability to treat $_GET['filters'] as an array directly, but at the cost of an uglier/longer URL.
Perhaps you should write 2 functions, "remove" and "add", which would each loop through the array looking for the value in question. Then the remove function could remove it, and the add function could add it. The functions themselves would not be so elegant, but using them would be simple elsewhere in your code.
This is probably considered a really silly question, but I'm in the process of putting together a simple template system for a website and am trying to keep track of my variable usage and keep everything neat and tidy.
Can you tell me if there is any advantage/disadvantage to the following methods:
simple var:
$tpl_title = 'my title'
$tpl_desc = 'my text'
array:
$tpl['title'] = 'my title'
$tpl['desc'] = 'my text'
Object:
$tpl->title = 'my title'
$tpl->desc = 'my text'
I like the object method the best as it looks clean when echo'd within html as opposed to arrays and afaik it can be used in an array-like way? However, what I want to know is whether using objects in this way is considered bad practice or introduces unneccesary overheads?
In ideal scenarios every variable should belong to an object, other than the variables local to methods for temp purposes. However we don't live in an ideal world and specially our programming languages are far from it. Based on what the situation is, choose the best way to go about it to make your life easier. If you are using things for templates, generally you keep all the data in an array and extract the array to get stand alone variables.
So yeah, the object method is the nicest, try to make it happen as much as you can without spending crazy amounts of time in doing it.
Also if you love objects and want to have the neat -> way of doing it, you can do
$object = (object)$array;
That would convert your array to an object.
Hope that helps.
I would consider it unnecessary overhead. Doing what you are talking about in an object-oriented way only means that inside your class you will have done nothing more than create a bunch of variables, just as you specified in your first example.
The array is the best way to go in my opinion. You are only using one variable, and you can also integrate it into your Class. So, instead of $tpl->title, you may have $tpl->text['title'].
Arrays
I would suggest on the backend part, keep everything stored in an array. This allows you to have only one variable to keep track of, and once you pass it to the frontend, you can extract() the array, to convert them into simple variables.
Syntax
Using extract() simplifies the syntax on the FrontEnd, which means you will only always have $varibles in the template.
On the backend you would set
$array['title'];
Which once extracted would in the template be
$title;
Example of a backend function
protected function fetch($template, $data = null)
{
if (!$this->isTemplate($template)) {
throw new Exception("Template file $this->_templatePath$template not found");
}
ob_start();
if (is_array($data)) {
extract($data, EXTR_SKIP);
}
require $this->_templatePath . $template . EXT;
return ob_get_clean();
}
In the end they are the same, It depends on the preference, although I would use arrays or objects because you can group variables in there, so you have things better sorted out.
Despite the objects method works I think it's not the natural intended use for it.
So I would say arrays!
Also, there are tons of php native functions you can use with arrays, like array_map() or array_filter() array sortings and etc etc...
In my opinion the cleanest way to set it up is in array like this:
$tpl = array (
'title' => 'my title',
'desc' => 'my text'
);
You can combine it with Zane's answer also.
All the best!
$tpl = array (
'title' => 'my title',
'desc' => 'my text'
);
Like Goran said, with the bonus that you could store these arrays in an ini file later and extract them as needed with parse_ini_file
Could be important if you want to permit users to write to their own ini file.
arrays and objects are useful in case if you want to reset bulk of variable data after use it.
you can simply unset the array or destroy the object instead of unset range of variables use in a code.
Other than this arrays and objects have more symmetry in code and explanatory than normal variables
I need a function with variable number of arguments, to access to the elements of a multidimensional array. I have done in this way ($this->_config is the array)...
function item()
{
if(func_num_args() != 0){
$config = $this->_config;
$args = func_get_args();
foreach($args as $item){
$config = $config[$item];
}
unset($args);
return $config;
}
else throw new Exception('An item index is required.');
}
Is there a way to do better? Thanks to all!
In your question you say you have a multidimensional array, so I take it is like this:
$config = array('foo' => array('bar' => array('baz' => 3)));
Calling item('foo', 'bar', 'baz') would run all the way through to the last array and return 3. If that is what you want, you could just write $config['foo']['bar']['baz'] or place your configs in an ArrayObject and use either the array access notation or $config->foo->bar->baz (though all nested arrays must be ArrayObjects too then).
If you want to keep the function, you should add some checking on the index before you grab it, because PHP will raise a Notice about undefined indexes. In addition, why not use InvalidArgumentException instead of Exception. Fits better for this case.
edit: removed some portion of the answer, because it was more like loud thinking
edit after comments
Tbh, I find it a rather awkward approach to reinvent array access through a method like this. In my opinion you should either pass the entire config or a subset to your objects during construction and let them take whatever they need through the regular array accessors. This will decouple your objects from your configManager and allows for easier modification at a later point.