Introduction
I have some sort of values that I might want to access several times each page is loaded. I can take two different approaches for accessing them but I'm not sure which one is 'better'. Three already implemented examples are several options for the Language, URI and displaying text that I describe here:
Language
Right now it is configured in this way: lang() is a function that returns different values depending on the argument.
Example: lang("full") prints the current language, "English", while lang() prints the abbreviation of the current language, "en". There are many more options, like lang("select"), lang("selectact"), etc that print different things. The code is too long and irrelevant for the case so if anyone wants it just ask for it.
Url
The $Url array also returns different values depending on the request. The whole array is fully defined in the beginning of the page and used to get shorter but accurate links of the current page.
Example: echo $Url['full'] would print "http://mypage.org/path/to/file.php?page=1" and echo $Url['file'] would print "file.php". It's useful for action="" within the forms and many other things. There are more values for $Url['folder'], $Url['file'], etc. Same thing about the code, if wanted, just request it.
Text
[You can skip this section]
There's another array called $Text that is defined in the same way than $Url. The whole array is defined at the beginning, making a mysql call and defining all $Text[$i] for current page with a while loop. I'm not sure if this is more efficient than multiple calls for a single mysql cell.
Example: echo $Text['54'] prints "This is just a test array!" which this could perfectly be implemented with a function like text(54).
Question
With the 3 examples you can see that I use different methods to do almost the same function (no pun intended), but I'm not sure which one should become the standard one for my code. I could create a function called url() and other called text() to output what I want. I think that working with functions in those cases is better, but I'm not sure why. So I'd really appreciate your opinions and advice.
Should I mix arrays and functions in the way I described or should I just use funcions?
Please, base your answer in this:
The source needs to be readable and reusable by other developers
Resource consumption (processing, time and memory).
The shorter the code the better.
The more you explain the reasons the better.
Thank you
PS, now I know the differences between $Url and $Uri.
It sounds like you're implementing ambiguous functions through the array notation. Normally, these would be classes with methods. $url['full'] would be $url->getFullPath(). Methods are preferred over the array accessor because methods are documented, and can be introspected by IDEs. Objects are more preferable because (in your examples) you can lazy-load the information. Right now, your script is compiling the $Url array and figuring out values for every possible key so it can be used in the script. Whereas a $request object could only do the parsing upon request - not instantiation.
I am using something like config array var. Where strings are set. Is better for later reading to use $LBL["hello"]='Hi!' than lbl(5). Think about yourself when you will return to your code aftre one year :)
Related
I may sound stupid to some but I want to know if there is some benefit of passing arguments to a function as an array,rather than passing each arguments or some downsides?
Unwritten rule for good programming practice is that function should not have more than 3-5 arguments.
Usually arrays or even objects are used to pass in the logical complete data structures.
I think this is due more transparent and readable code rather than any performance benefits.
Sure it might look nicer if you pass an array to a method, but what does it mean?
Arrays usually signify that you have a collection of the same thing, whilst method parameters are usually different things.
If you want to pass a list of things to a method and do the same action on all of them, then it makes perfect sense to use some type of array/collection object.
If however you want to make it tidier and avoid passing around lots of objects together, consider refactoring your code to use some kind of wrapper object that you can pass around more easily.
Also if you have so many arguments that you would consider using an array to hold them, it's a sure sign that you need to refactor your code ;-)
Mostly it just requires more typing to create an array and pass it, rather than just passing individual arguments.
Other than that there's no particular specific advantage to separate parameters.
Parameter list much more clear when you read function signature. Array is just one variable, say, $args. But what there in args?
if you have this array already, it is surely better to use it.
if you don't have this array already, using parameters will save you typing of array keyword and a couple of braces.
that's all.
Use whatever you feel more suitable for the case.
I think that when you have a few parameters or less than 5 (subjectively) then more useful is passing arguments as parameters. If you have a big count of arguments then using array is more useful that function/method with 15 parameters.
Well, I read in my handy PHP book that it's very important to be able to distinguish between reference and variable parameters. The book says that the original value of parameterized variables are preserved when the variable is changed, and the original values of parameterized references change when the reference is changed. It says that's the key difference, if I am reading right.
Well, I'm wondering when each is more useful than the other. How do I know when to use variables and when to use references when I create my own functions?
It's pretty straightforward. Use references when you need to modify the value of the variable passed in to the function. Use variables when you don't need to or want to modify the value.
So, for example, if you're writing a function that takes an array and changes that array, you'd be better off using a reference for that array rather than returning a new array from the function.
"References" (variable aliases) make your code harder to understand and could be a source of hard to follow errors. There are no valid reasons to use references in php and to be on the safer side try to avoid them altogether.
And no, objects in php5 have nothing to do with "references".
"References" as implemented in php is a strange concept. Normally, in programming languages variables are independent of each other so that changing one variable doesn't affect others. Php "references" allow several variables to share the same value and to be dependent of each other. Basically, you change one variable, and suddenly another one, which you think is totally unrelated, is getting changed too. It's no good thing and often leads to much confusion.
Objects in php (do I need to add 'five'?) have nothing to do with "references" in the above sense. They behave much like C pointers (actually, this is what they are under the hood) - when you pass an object to a function, you actually pass a pointer, and the function can use this pointer to manipulate the object contents, but there's no way for the function to change the passed variable itself, for example, make it point to another object.
This "objects are references" misunderstanding is probably because people confuse php "references" (ampersand syntax) with the generic CS term , which also applies to pointers, handles etc.
Is there a naming convention or maybe some guideline on how to name function parameters?
Since forever, I have been doing it like this:
function divide( $pDividend, $pDivisor )
{ ... }
That way I'll always know which variables were passed as parameters.
(This one's PHP, but it should be applicable to most programming languages)
Is there one major reason against this?
Is there a better way to do this or is it probably best to just avoid such naming schemes?
If :
your functions/methods are well written and short (as they should be)
the variable names are descriptive enough
This practice is not needed.
If you need this, it means that the code written is not readable enough (functions/methods too long), cryptic variable/function names, bad OO practices, shortcuts, code debts, etc. :)
So it would be a signal that the code needs to be refactored/improved.
I think taking the advice of Code Complete regarding naming -anything- would be justified it's whole chapter 11 is on naming variables properly):
Don't name it j, k, i, m, n (unless it's just for an iteration) or "placeholder" or "test". When the "test" works, I often don't take the time to rename the variable wherever it's been listed.
Call it a descriptive name that's separate from the code's function ie "EmployeeComments" not "XMLEmp_Comment_File" because a lot of that information (XML, external file) could change, but that the program's working with "Employee Comments" won't
Keep it as broad and human readable as possible so you're coding in English (or your language) not $j=$k/sqrt($pi); or something equally unintelligible.
As for parameters specifically, I've never used the P notation. I like the idea, but if you named them right wouldn't it be clear they were the parameters for the function?
I've heard that some people will keep their function parameters one style, with the type of data a the first part of the variable (array = arr), and then capitalize the following words:
$arrFormData
where the rest of their variables are in a different style, where the words are all lower case, no type definition, and the words are separated by underscores.
$form_data
Personally, I tend to keep my variables the same as the rest of my variables, purely because on the first two lines of a function, I'm making sure that they are what I expect, or throwing an exception. After that, there shouldn't really be a difference between local variables and variables passed in. But, if it keeps your code clearer to type it one way, by all means.
You should follow general guidelines for how to name parameters as you would for other variables (names should be clear, accurate, specific, consistent, and usually 8-20 characters long).
As for the prefix, I would recommend the opposite: leave the parameter unmarked, and mark anything that you do with the parameter in the function as a separate variable. For example:
function upperCase($title) {
$upTitle = ucfirst($title);
return $upTitle;
}
In my example, I use a bare parameter, $title. After I transform the input, I call it something else to indicate that it is now in a transformed state, $upTitle. That way I know that it is no longer just the function parameter. Merely calling your parameter $pTitle does not give you quite the same advantage as this consistent approach.
If you think about it, your method marks all the parameters on the interface, which is not the best level. If you look at the API of your program, all your function parameters are marked with $p meaning parameter, which is redundant. You are saying, all of my parameters are parameters, which we already know since they are part of the API. So I would recommend dropping the prefix for the parameter and instead using a series of semantic prefixes that denote what you have done to the parameter to transform it within the function, as in my example.
I disagree with the previous suggestion that you should just make your code more clear. Having clear code does not remove the need for having clear naming conventions.
I have naming conventions for some variables, like member fields or static fields, because the declaration of the variable may be far away from the code where I use it. For parameters or local variables I do not use anything, as usually the variable definition is about ten lines away.
Especially in the all IDE camp people seem to get more and more to dislike any prefix or suffix, as "the IDE provides highlighting". Well, it doesn't help me, and I dislike having semantic information only available as color. However, I can see there point, as the variable name should make the most important information clear, and if it doesn't, nothing helps.
So, this is more about style. Good naming is more important than good prefixes. For the schemes: pick one, stick to it. This will help the poor maintenance developer. Yes, those are the people who usually also prefer { } around single statement blocks and so on, but it helps.
The greatest chance for confusion for me is in member functions. If possible, I like to see differences in naming between:
local variables: index
class member variables: m_index
class static variables: ClassIndex
global variables: INDEX
This can make it easier to track down what's happening where. However, I agree with Toto that it's best to make your functions short enough so that these conventions don't make or break your ability to figure out what's going on.
You can follow the PHP Coding Standards or Coding standard for php which is suggested to contribute in core php.
So after looking at all this, I decided to go with:
ClassName
methodName
propertyName
function_name (meant for global functions)
$variable_name
There are many ways to name variables (as you can see from the answers)
But as a general rule, they should be named such, that it is clear from just looking at the variable itself, what it does and what it is used for, right there and not have to go through thousands of lines of code to find out - and not just for who else might have to troubleshoot later but if your code is thousands of lines long for your own good if you yourself have to troubleshoot later
AND WHATEVER NAMING CONVENTIONS YOU CHOOSE BE CONSISTENT THROUGHOUT YOUR CODE - this cannot be iterated enough :)
Personally I use the following:
first part of the variable is for what it is
second part is for what it does/is used for
and for variables needed outside the function, class, etc. the third part is for the function, class, etc. it comes from
Ex:
I want to name the variable for a video thumbnail on the front page:
so i start with what it is (lower_case) - thumbnail
then I add on what it is used for (first letter upper_case) - Video
and since I need it on the front page outside the function I finish off with the function it came from (seperated by under_score) - getVideoAll
Giving me $thumbnailVideo_getVideoAll
That way no matter where I look at the variable in any part of the code (HTML, PHP, etc.) I know...
ah this is the thumbnail for the video I'm trying to show and if it for some reason doesn't work I firstly don't need to go anywhere to spell-check and secondly I know exactly what function, class it was called for (getVideoAll) and can just go there to troubleshoot
If I instead just had named it $tnVid I might personally have a vague notion of what it is but someone else looking at will have no idea that tn stands for (t)humb(n)ail, etc.
so to troubleshoot they would have to first look at the surrounding code to maybe infer that it is probable a variable for a thumbnail and second go through thousands of lines of code to find what function, class, etc. it came from - and that's hours of work just finding what you need to even start troubleshooting - instead of the 5 seconds it takes seeing $thumbnailVideo_getVideoAll and going -
ah this is the thumbnail for the video and I need to go to the function getVideoAll to troubleshoot
I'm reading programming best practices and it is said that when creating a function we should make it do a only single specific task.
I got model functions that retrieves data and it's related data. Example:
$this->Student->StudentAssignments();
Currently this function retrieves the student's assignments plus the question for each assignment and data about the student. I use them all. My dilemma is if I try to make separate functions that retrieves the related data (student and question datas) it's taxing since I'm producing more calls to the DB.
What would you guys suggest?
Something to keep in mind when doing this sort of refactoring...
I typically will have a Model->getSomethingAndSomethingElse functions in my models.
These functions are public and meant to be called as a substitute for doing complicated (or any) find calls from the Controller.
What I will usually do is then build up a small collection of private functions in the model.
In your case I might have something along the lines of...
Student->getStudentAssigmentsWithQuestions
that then calls some private functions i.e.
Student->getStudent which might call Student->joinStudentAssignment which in turn might call Assignment->joinAssignmentQuestion etc.
The double underscore prefixes have been removed since markdown wants to bold things because of them. If you are using php5 the underscores aren't really important anyways as long as you use the "private" or "proteced" keywords.
Basically I use the public method as a container for a group of very specific query building or association building private functions within the models. This allows me to have an api that has complex data returned, but I build the query or the result set (depending on the type of data, relationships involved or query complexity) from small pieces - that can ideally be purposed and used in more than one public function call.
I think you're doing fine. But you should reconsider renaming your function to
$this->Student->getStudentAssignmentsWithQuestions
Or whatever you think fit. I think one should try to do as few calls to the database as possible (I assume you're performing a join somewhere in there), instead of fetching each set of elements by specific methods. This can lead to the fact that you'll get more methods (and therefore have to write some more tests), but I think this is the right way to do it.
To defend the design argument:
Your method does just one single task; it fetches student's assignments with each assignment's questions.
No, if you're strictly concerned about code refactoring you should break down that blob into simpler functions that perform a single task as you said. Yes, you will hit more your database but considering how easy is to work with caching in cakephp, performance should not be an issue. And if it is, then you shouldn't worry about code refactoring at this point.
Is it considered 'bad practice' to create an function like so:
// $arr_member_fields['first_name'] = $_POST['first_name'];
// $arr_member_fields['last_name'] = $_POST['first_name'];
// $arr_member_fields['email'] = $_POST['email'];
// $arr_member_fields['dob'] = $_POST['dob'];
// $arr_member_fields['gender'] = $_POST['gender'];
function update_member($int_member_id $arr_member_fields)
{
//some code
}
Or should a create a function with no array and just use variables instead -- like so:
function update_member($int_member_id, $str_first_name, $str_last_name, str_email, $str_dob, $chr_gender)
{
//some code
}
The reason why I prefer the first method (the one with the array) is that I always have the option to loop through the array for database insertion/updating purposes.
Very curious to know other peoples inputs on this.
Depends on the function. There is no best practice here that will adequately capture most cases when writing a function. What if you don't need to loop through the arguments?
Seems like you're best off passing arrays in this case.
This is a case where I would consider a structure to hold the data. That way I can pass the structure or an array of structure to a methods or I can access individual elements of the structure.
Of course if I wanted to go further I'd made a class instead of a structure. Then I can have methods as well as data, setters, getters with validation, and so on.
Things like this ultimately come down to effects on performance and code readability. While passing an array is extremely handy, it also makes it difficult to follow for someone else reading your code (or even for you if you're coming back to it 6 months later). This is especially true if the array is defined somewhere else in a large file, or another file altogether.
At the end of the day it really comes down to why you're trying to optimize your code in the first place. Is it for performance, or to make it easier to understand/read?
If it's for readability, pick the approach that seems easiest to understand. You'll thank yourself when you have to go back and tweak something months from now.
If it's for performance, make sure you actually need to improve performance and that you aren't optimizing something just for the sake of optimization. More often than not, you'll create a very real readability problem in an effort to solve a nonexistent performance problem.
I would go with the second method because your IDE can tell you what parameters it should take without having to go to that file. It might seem ok to use an array now for a small project, but as your project becomes larger its likely to become a problem later. It will also save you from asking yourself later when you're trying to use it "Did I use name_ first, or first_ name?" Those fields look like something that would all be in one table, which would be updated in a single statement anyway, so I don't see any reason you would want to loop over the array.
I think that passing parameters by array is generally a bad idea. If parameter lists are so long that they justify being passed as an array it's probably a sign that the code is not designed in the best way.
Passing parameters in an array is more difficult to document using something like PHPDocumentor and will also not be picked up by the code-completion in an IDE. Passing parameters explicity also allows for type hinting and is more transparent to the reader of the code.
Obviously if you are passing an array of items to be processed as a function argument then it makes sense to pass it as an array.