How to define global functions with Laravel - php

I have found a few guides like this http://www.mackhankins.com/blog/defining-your-own-helper-classes-in-laravel-4 but it isnt really what im looking for as i want to be able to use functions to modify values that arent members of a class.
I have a lot of regex functions that will modify strings if they match a pattern and return a modified string. I want to be able to call these functions as if they were built in php functions. is what i would have always done in the past, but i want to do this right.
This post What are the best practices and best places for laravel 4 helpers or basic functions? seems to be getting closer, but im still not clear on why i would have to instantiate an object just to run a basic function.

Just plop all your custom functions in a file names something like "helpers.php". You don't need to do anything special.
You could either directly include the file in your bootstrap file or just set composer up to auto-load it.

Related

Should i write all my function in an utility-class or in a service-class?

I am currently working on a project which dealing with XML in text file. I want to extract the content and i want to add it to the table tt_content. My question is where should I put the all functions (upload-file, extract-content,insert-tt_content)?
Utilities are for static functionality that does not depend on a state. Good examples are PathUtility and StringUtility. Once you call a function, it gets the job done and nothing further.
Services on the other hand can handle state and are usually more complex. You could have some kind of DownloadService that is initialized with an URL, then fetches it and finally does some kind of post processing. A core example would be the MarkerBasedTemplateService.
As a rule of thumb, a utility does not have dependencies and does not call other (non-static) methods. Services are more complex and might call other services. Services may have an internal state.
Also make sure to check the core documentation regarding architectural guidelines: https://docs.typo3.org/typo3cms/CodingGuidelinesReference/latest/PhpArchitecture/ModelingCrossCuttingConcerns/StaticMethods/Index.html
You can write your functions into a UtilityClass or in a ServiceClass or (I think the better way) you use both. Group your functions by task, e.g. StringUtility, FileUtility etc. Your ServiceClass use than the needed UtilityFunction.
So you have little functions and you can use it again and again. For example have a look in other great extension as tx_news, femanager, etc.

PHP Global vs Javascript Global

When I was learning javascript, the global variable issue was emphasized by book or tech article authors, a.k.a one should always try to avoid using global variables. One of the reasons I believe is to avoid naming conflict. And I think no matter what language we are using, naming conflict will always be an issue.
However, when I read PHP books, using of global variable is not perticularly mentioned or marked as bad practice. So shall I pay attention to it?
For example, I am trying to modify some PHP file in Joomla. if I write a custom function getJson() in a template file of a module, how do I know the function name is not being used somewhere by other components?
Your first question is about a variables the second about function names.
Is using of global variables bad pratice?
Yes, if you are using too many variables and lose the overview about the useage!
Think about a coder team with 20 coder on one big project with 1000+ files.
No, if you use globals wisly.
Like the most Framework do.
Topic: TO OOP OR NOT TO OOP (Object-oriented programming)
So shall I pay attention to it?
In your case, using Joomla, you should take a look how and for what Joomla is using global vars. And use them in that way too.
In your other projects, give them an custom useage,like: global vars only for class instances.
Its all about how you code, more OOP or more PROCEDUAL or all mixed up ....
php is a big open world.
how do I know the function name is not being used somewhere by other
components?
function_exists('getJson'); ;)
Whatever, for this problem php has namespaces.
namespace MySpace {
function getJson(){}
}
use MySpace\getJson as getJson;
getJson($args);
You should read a little about it.
if I write a custom function getJson() in a template file
You can do with a anonymous function:
$getJson = function(){};
instead of creating a global function.
If the function is only used in this template!
Hope that helps a little.
Investigation is key in your situation.
Make sure error_reporting(E_ALL); is set in your development environment.
Before creating the function, run a recursive search through all of your PHP files for some combination of function getJson(
I am not familiar with Joomla but if namespacing is being used then you may run into false-positives.
If namespacing is being used then make sure to not run into namespacing conflicts by referring to first point - error_reporting(E_ALL);
Use namespaces like a boss (requires PHP 5.3.0 or later):
namespace NameSpaceThatIsDefinitelyNotUsedanywhereksdgbdihjfgbdfbgd{
function getJson(){}
}
use NameSpaceThatIsDefinitelyNotUsedanywhereksdgbdihjfgbdfbgd\getJson as getJson;
getJson($args);
Instructions for #2
Choose your directory
Limit your search to PHP files only
Tell it you want to search for function getJson(
Click "Find All"

CodeIgniter: Appropriate place to put reusable functions with database calls

I'm new to CodeIgniter but want to perform best practices from the start. I have a simple authorization call that needs to be able to be called from several controllers. Hence I'm thinking it should be placed in either a library or a helper function. The call would take the user's id and a required authorization "level", grab their information from the DB, make sure they have that level of access, and return true or false.
Let's say:
auth($user,5)
My first instinct is to make this a library, but it seems odd to place it directly in a library because there are DB calls, which I would think should go in a model. It appears that only the Session library contains calls directly to the DB (for when database session storing is turned on).
So, I could access the DB directly within the library, or try to link to an external Model. Looking it up on the web, I'm only finding people who have trouble with both routes. Before I dive too deeply into getting one of them to work, I'd appreciate any opinions out there on how to go about this.
Thanks,
Jeremy
It seems like that is a model function. At least put it there until later in development.
If you later find there is a need for multiple models which would require duplicating the function, then would be a good time to move it to a helper or library.

Where to put big, rarely used functions in codeigniter

I have a several functions which are quite large, and are only used in one controller function each, and I'm wondering where to put these? They are not displaying any views, but instead crunching some numbers.
If I'm not wrong, there are 4 possible places where i could put these function: in my controller, in a helper, in a library or in a model. But none of these seem appropriate, since I don't want the code to be loaded every time a user uses the controller, and model should be used to do database stuff, and helpers and libraries should contain code that can be used over and over again.
If it is business logic, the best place to put it is in the controller as a private method, then you can call that method from within the controller.
Just as a note, helpers aren't always loaded unless you autoload them or load them in the constructor of your controller. So, as an alternative, you can make these methods of a helper then just load the helper in the controller action you wish to use them. That way they only get loaded when you need them.
CodeIgniter comes with helpers that you probably might not use (doesn't load unless you specify it in the application/config/config.php file) and I don't think its a problem having functions that you only use once stored there (application/helpers ). For example I might use a random password generator once only, but its still there and won't be loaded unless I call it.
$this->load->helper('my_string_generators');

How to leverage PHP's autoloader functionality in such a way, that it searches through a defined set of paths?

One bad thing about using the autoloader is, that it doesn't know where to look at. My framework already has about 70 classes in about 15 different directories. Because of that, I didn't go for autoload, but instead struggle around with generating paths. So I have an associative paths array that give me paths from my root file to where I want to go. It works, but it's really becoming a pain.
First, the user of my framework will very likely have no big idea where a class resides. So creating a FormViewController is already a pain just because you need the path to include it.
For the beginning, I think it would be just fine if PHP had to "search" for the file through multiple directories when it wants to autoload it. So what? Shall PHP do so and save us a lot of pain. But how could I do that most efficently?
Ther's an array called $paths which I get out of a global context object. The paths could be defined in the array in the most reasonable order: Starting with the most frequently used paths.
I know the PEAR library has a funny naming convention like system_views_specialviews_SpecialView.php which gets converted in the Autoloader to system/views/specialviews/SpecialView.php ...but honestly, that's horrible. Don't want to mess up my file names like this. For the developer who creates his own classes that would suck just straight away.
Before I re-invent the wheel for this task, maybe someone knows a solution for this?
NB: I'm presuming you're creating your own custom autoloader via spl_autoload_register, etc.
If you're creating an autoloader and the classes you're looking to include are spread across 15 different directories, I don't see how you can hope to avoid using some form of class name to directory path mapping, although this obviously doesn't need to be quite as deep as the example you quote.
At a simple level, if you keep all of your system libraries in a single area, then a quick case match as such...
switch(true) {
case substr($className, 0, 6) == 'System': { $libraryPath = 'xxx'; break; }
...
}
...should be reasonably efficient approach, although it obviously depends on how many paths you need to manually check.
Additionally, I presume you're checking for the existance of the class prior to attempting to autoload? (i.e.: You're doing a class_exists($className) to ensure it's not already been included.) Then again, the requirement for this depends on how often you re-use objects.
You might want to look at Nette Framework's RobotLoader.
Basic idea is that it scans through directories you specify, parses .php (token_get_all) files and finds out in which file are which classes/interfaces. Locations of classes/interfaces are cached, so it is fast. Loader is registered with spl_autoload_register() and when PHP interpreter cannot find some class, it calls loader's tryLoad() method.
I'm sure you already know this, but just in case, you can write an __autoload() (API) function that takes the class name as a parameter in your front controller (or in any file included by it) that searches your directories based on any criteria that you want. All you do is require_once the correct file once you've found it, or throw an exception if the class name isn't valid.
From your description, I didn't get any indication that you were doing this. It sounds like you are just appending PHP's include path with values in unwieldy global arrays.
The PHP Autoloader does all you want. If you have different locations you just have to create several instances of the autoloader for each class path.
It seems it does the same like the mentioned RobotLoader, except the first searching is done with some intelligence. Files with lower Levenshtein distance to the class name are prefered as potential class definitions. But this is only relevant for the first search without the index.

Categories