I'm making a model in CodeIgniter and I don't want any of the functions to be accessible to the user. For controllers you would do something like:
private function _myfunction()
{
dosomething();
}
I know this will also work for models but my question is, is this needed? I don't think users can initiate these functions via the URL. The reason I'm asking is because I'd like to follow best practice but if possible I'd also like to avoid prefixing everything with '_' when I call it.
No, that is not necessary. It's an unusual situation for a user to have access to a class method through URL, and it's only implemented in codeigniter for controllers.
It's not necessary, and in fact prefixing private objects with "_" is depreciated with the actual use of the "private" and "protected" keywords in PHP 5+.
No its not necessary. To prevent access to the method from the browser, just add an underscore before the method: _method() . This is Ideal if you want to use/call it as a module(HMVC).
Related
In my efforts to rewrite a past project of mine with OOP in mind, I have broken my code up into classes such as Devices, Facilities, etc.
Before moving to a more object oriented approach, I just stuck all of my helper functions in an included "functions.php" file. Using Devices as an example, would it be best to have a Devices class for my object specific properties/methods, then have a DeviceManager class to store functions like getDeviceByName, getDeviceByID, etc?
From what I am understanding, OOP is more about readability/manageability than anything else, why I assume the purpose would just be to have something like DeviceManager::GetDevice("Computer1") in place of GetDeviceByName("Computer1")
If you are thinking of using a class as a namespace then you can just as well use an actual namespace:
namespace MyCollectionOfFunctions;
function printMyName($name) {
echo $name;
}
And then you can use the functions like this:
use MyCollectionOfFunctions as fn;
echo fn\printMyName('Brett Powell');
There is nothing wrong with functions. Do not let anyone tell you that they belong is a class, as static methods. It can be done that way, but since we got namespaces there really is no reason for it.
In a OOP languages like C# or Java, you simply can't have functions outside a class, so there's no issue. That doesn't mean you're doing OOP, which is a mindset.
In PHP you can either put the relevant functions into a nampespace or within a class (inside a namespace). It's up to you, there's no right or wrong approach. Personally, I'd put them into a class because that's how I'm doing it in C# and it'll help a bit with productivity: I group related functionality in one place (class). It's easier to manage.
But strictly from a programming point of view, there's no difference, your code won't be cleaner/decoupled or more OOP because you've put functions into a class or namespace
A few advantages when using Namespace or Class for static functions.
Namespace and Class Name helps distinguish functions. You can avoid naming conflicts.
DPDate::FirstDayOfMonth() is better than FirstDayOfMonth() when you want to take advantage of auto suggestion of the IDE.
It is really all about cohesion and decoupling.
You must following this rules:
In OOP you MUST ALWAYS use a CLASS
Your method must have a single responsability
Avoid generic helper classes, classes must have a simple and specific responsability
Don't use static methods, use strategy (pass the object throw the param) to call a method, this way you can create a Mock to test your methods.
Avoid private methods, this make dificult to test your classes
Keep this things in mind, and you will gona make a clean code. =)
Answering Eric about item 4: This code it will use static method:
public function myFunction() {
$deviceId = DeviceManger::getDeviceId('computer 1');
// Rest of code using the device id
}
This way i cant mock the return of Device ID, this way i can:
public function myFunction(deviceManger) {
$deviceId = deviceManager->getDeviceId('computer 1');
// Rest of code using the device id
}
The code with mock in test function:
$deviceManager = $this->getMock('DeviceManager');
$deviceManager->method('getDeviceId')->returnValue(1);
myFuncion($deviceManager);
I built some the following i18n function which is called several times when rendering view :
function e_($text)
{
$t = Translate::Instance();
vprintf($t->_($text), array_slice(func_get_args(), 1)); // outputs translated text
}
Currently, I get the instance of the Translate singleton Class inside the function.
I've read that dependency injection should be used instead.
But If I do use dependency injection, I will have to pass the Translate object each time into the function, right ?
This would became :
<?php e_('my text', $this->Translate);
and not simply <?php e_('my text'); ?>
Well I'd like to avoid that.
The way you use the e_ function is actually using an alias. That's fine as long as you can live with it. You don't need to use a singleton to implement an alias:
function e_($text)
{
return $GLOBALS['e_alias']->alias(func_get_args());
}
When setting up the view layer, set the dependency:
$GLOBALS['e_alias'] = $translate;
In application context, set the global variable $translate. This will allow you to move away from the singleton (which are liars), and you actually only need a global variable.
Additionally it allows you to test views with the e_ alias against different translation implementations.
The downside is that you need to manage a list of all these special global variables, like you need to maintain for the global functions like e_.
See as well this answer to the Getting $this inside function question.
True. The reason you would use dependency injection instead is so that you could swap out the translation method for any particular use of e_().
In this particular case, I'm not sure it would be worth it unless you wish to test different translation methods during testing.
One thing you could do to help a little with performance is make $t static so that Translate::Instance() is only ever called once no matter how many calls to e_() are made.
I am writing a pretty basic php app and have created a pretty big mess of functions to do various things, e.g. display_user_nav(), display_user_list() etc. I want a way to organize these in a logical way. What I really need is something like a ruby module, but I haven't been able to find a php equivalent. I also feel that from a programming standpoint they don't belong in classes, as I already have a User object to contain information for one user, and don't want to have to create and store a new object whenever I want to use them.
What I am doing now:
display_user_table()
display_user_edit_form()
What I kind of want to be able to do (sort of like Ruby):
User_Functions::Display::Table()
User_Functions::Display::Edit_Form()
Any suggestions are appreciated.
If you are using PHP 5.3+, you have namespaces available.
So you can name your functions (the namespace separator is \):
User_Functions\Display\Table
User_Functions\Display\Edit_Form
However, it seems like using a class for this wouldn't be a bad idea. If you feel that display functions don't really belong to User (the same way many people think serialization methods don't make sense in the target objects), you can create a class like this:
class DisplayUser {
private $user;
function __construct(User $u) { $this->user = $u; }
function table() { /* ... */ }
function displayForm() { /* ... */ }
}
how about Abstract Classes!? or singletons? thats a good way to organize your code
Well you could break them out into helper classes for example:
$helper = new UserHelper();
$helper->renderTable($user);
$helper->renderForm($user, 'edit');
The architecture of the helpers could be more complexx and implement a fluid interface or something to that effect depending on how your classes operate.
Another approach might be to attach decorators to your objects to perform these functions.
There shouldn't be such functions at all but a template that takes care of all HTML output.
The problem is you are using functions in a wrong way: make a function only to repeat some operations more than once.
Do not use a function for just single operation.
When is the right time to use functions to set variables inside of my models, verse simply directly assigning them?
AKA...
When do I use:
$model->set('status','active');
...instead of:
$model->status = 'active';
using getters and setters is good for the encapsulation of code. It's always a good idea to use them.
Think about this:
What if your model has some variables that you don't want to be able to be read or changed (or both)?
What if you ever need to do something besides just getting and setting the variable? (for example, sanatizing data)?
If you're using a recent version of PHP (5.x), you can get the best of both worlds with the magic methods __get() and __set(). (PHP reference). Any access to an undefined property will be routed to the appropriate get/set function automatically.
I must admin that I'm not certain if this is really a good idea to use or not, but it seems like a decent fit for a base model class in a MVC system.
I have recently learnt about namespaces in PHP, and was wondering, would it be bad practice to do this?
<?php
namespace String; // string helper functions
function match($string1, $string2)
{
$string1 = trim($string1);
$string2 = trim($string2);
if (strcasecmp($string1, $string2) == 0) // are equal
{
return true;
} else {
return false;
}
}
?>
Before I had this as a static method to a String class, but this always seemed wrong to me... Which is the better alternative? I have a desire to categorise my helper functions, and want to know which is the better way to do it.
Edit
So how do I then access the match function if I have declared it in a namespace? How do I stop the namespace declaration, say if I include a file beneath it which declared a new namespace, would it automatically stop references to the first? And how do I go about returning to global namespace?
I'd put it in a namespace. A class is a describes a type in php, and though you maybe operating over a type with a similar name, it's not the same type, strictly speaking. A namespace is just a way to logically group things, which is what you're using a class to do anyways. The only thing you lose is extensibility, but as you said, it's only a collection of static methods.
If they're all string-related functions, there's nothing wrong with making them static methods.
A namespace would be the better choice if you've got a bunch of global functions and/or variables which you don't want cluttering up global scope, but which wouldn't make sense in a class. (I've got a class in my own code which would be a lot better suited to a namespace).
It's good practice to stick everything in some sort of container if there's any chance your code will get reused elsewhere, so you don't scribble on other people's global vars...
As for your edit there:
Namespaces are tied to the file they're defined in, IIRC. Not sure how this affects included files from there but I'd guess they aren't inherited.
You can call the global scope by saying ::trim().
Because namespaces are so new to php, people have been doing for a long time what you did - create a class, add static methods, and use the class as if it were a namespace. It looks to me as if you are thinking about it properly.
You would use classes to categorized some sort of functions on a certain dat. Like let say you have a Student class which will hold student information and student age and student ID number;and alose there some sort of methods that return and set these data.
Moreover, you would use namespace to categorized the Classes;let say now you have another class which handle the University registration for those students and alose the other classes for managing courses. Personaly, I would put all these classes under a category (i.e. namespace) called University.
Thus, it is not even a bad practice, also it gives you more readability in your code. And that would be more underestandable for other programmers if you are working in a group.
So personally I strongly suggest you use those in your project wherever you think it is proper to use it.
Ideally, it would be best to put functions in a namespace. If you depend on autoloading though, which only works for classes, you need to put them in one or more classes.