in C , i can define a function to be static so it can only be used in it's own file.
in python , i can define a function with it's name starts with _ so this function can't be used outside this finle.
could i do it in php ?
If you really mean "functions": No, both arent possible.
First: Functions are always static.
Second: In PHP namespaces are not bound to a file. So a file can declare non, one or more namespaces. On the other side a namespace can be declared in different files. Its difficult to define a consistent way on how non-public functions can get resolved. You can use static classes instead.
A class can be used to for data hiding and implementing encapsulation.
You can use private keyword to declare functions in php to hide them outside of code but the all are bounded with class.
Only class can use these type of functions.
class A
{
/* This method will only be accessible in this
class only by the other methods of this class
and will be hide from rest of program code*/
private function setValues()
{
//some stuff
}
public function getVal()
{
$this->setValues();
}
}
The method above can only be accessible by this class.
Related
Consider the situation where there are multiple classes that all need to have access to the configuration storage mechanism, but cannot be extended from a base class because of the architectuur of the framework.
In addition to that I wanted to keep the storage mechanism flexible (be able to switch storage backend later).
I felt it would make sense to create a trait which does the actual saving and use those functions inside all classes (for the example I use $_SESSION as storage system):
trait MyTrait {
function setting_enabled() {
return !empty($_SESSION['setting']) ? TRUE : FALSE;
}
function enable_setting() {
$_SESSION['setting'] = TRUE;
}
function disable_setting() {
$_SESSION['setting'] = FALSE;
}
}
This works great from classes. There is however also one file that is not a class, but is just plain PHP, for which I also need to know if the setting is enabled.
I have tried declaring the function as static:
trait MyTrait {
static function setting_enabled() { // Declared as static function
return !empty($_SESSION['setting']) ? TRUE : FALSE;
}
...
}
And then call the static function from the trait, which worked fine.
if (MyTrait::setting_enabled()) {
...
}
It however feels not entirely right. On the other hand, creating a new empty class that uses the trait and instantiating that to obtain the value seems like a lot of overhead.
Am I allowed to do this (as of PHP 5.6, but also considering the future with PHP 7.x)?
PHP does not allow calling trait's methods without some class (no matter if static or not).
A simple workaround is to use an anonymous class mediately:
...
(new class { use MyTrait; })::myMethod();
...
I like this way a little bit more because we don't create an unnecessary class name.
If you have a trait then you decided to make a multiple inheritance once, maybe for multiple classes. Otherwise, it's redundant declaration and you have to use a class. In fact, and existing of trait means its using.
If you have a static function inside trait, then why you can't using its from the class you'd implemented trait in?
trait MyTrait {
static myFunc() {}
}
class ThatUsingMyTrait {
use MyTrait;
}
// pretend below a code where you want to use the trait.
if(ThatUsingMyTrait::myFunc()) {
// do something
}
The code also is may be a class you want to implement without trait directly.
Hope I describe the idea understandingly.
unsure to import your trait be truing to resolve it:
In case of non-static method
(new class { use MyTrait; })->myMethod();
but it seem it deprecated on php 8
What's the difference between creating a Global function in a Namespace (and calling it from the global namespace):
<?php
namespace MyNamespace {
function MyFunction($x, $y) {
return $x + $y;
}
}
namespace { //global code... in a new file
var_dump(MyNamespace\MyFunction(1,2));
}
and creating a static class method, and calling from the global Namespace?:
<?php
class MyClass {
public static function MyFunction($x, $y) {
return $x + $y;
}
}
var_dump(MyClass::MyFunction(1,2));
Is there any reason to prefer one method over the other?
Is there any reason to prefer one method over the other?
(below assumes you're asking/referring to a difference between a static class method and a function in a namespace)
Historically (before namespaces arrived), people were forced to use classes with static functions to not pollute a global namespace. This is one of the reasons you're likely to encounter this method more often.
You might prefer to use a static method if you need access to class's data or if you think of leaving a door to overriding them in descendant classes (the so-called 'flexibility and functionality' by some).
You might prefer a namespaced function when all you want is ...uh, ahem... a function. Think of some util, functional or collections functions like compose/partial, retry , filter/map/some/every etc. You are probably not expecting this to be overwritten in a child class, right? Neither it need access to some static class member.
There is one particular annoying problem with (namespaced) functions though, that classes don't suffer from. And it's autoloading. To put it short, there is no way to autoload a function at the moment. And this is another reason you'd likely encounter classes with static methods (when they don't necessarily need to be) more often in practice.
The primary difference is the global namespace can only ever have one function named MyFunction.
Using namespaces, each namespace can have it's own copy of MyFunction. This allows you to flexibility to create a common API without having to come up with clever names.
For example:
namespace Mail {
public static function send() {
// Send Mail
}
}
namespace SMS {
public static function send() {
// Send Text Message
}
}
That wouldn't be possible with a single global namespace. But now you have a predictable interface to call Mail\send() or SMS\send().
For classes, the ability to create these contracts works much better than functions within a namespace, because you get the ability to build interfaces and use abstraction.
For example:
abstract class Mail {
public static function send() {
// Create empty implementation (have to do this because it is static)
};
}
class MailChimp extends Mail {
public static function send() {
// Send Mail
}
}
class MailGun extends Mail {
public static function send() {
// Send Mail
}
}
With that, we can now namespace things under "Mail", but also effectively under the specific implementations of mail, and keep the common send() API we've come to know and love.
Is there any reason to prefer one method over the other?
Either will work. You just get more functionality and flexibility when dealing with classes.
Let's say I have a class:
class test {
public static function sayHi() {
echo 'hi';
}
}
Call it by test::sayHi();
Can I define sayHi() outside of the class or perhaps get rid of the class altogether?
public static function sayHi() {
echo 'hi';
}
I only need this function to encapsulate code for a script.
Maybe the answer is not a static method but a plain function def?
A static method without a class does not make any sense at all. The static keywords signals that this method is identical for all instances of the class. This enables you to call it.. well.. statically on the class itself instead of on one of its instances.
If the content of the method is self-contained, meaning it does not need any other static variables or methods of the class, you can simply omit the class and put the code in a global method. Using global methods is considered a bad practice.
So my advice is to just keep the class, even if it has only that one method within. This way you can still autoload the file instead of having to require it yourself.
Functions in OOP are public by default, you can modify them to private like:
private function test(){
//do something
}
Or like you said, to static, in public or private like:
private static function test(){
//do something
}
But if you're not using OOP, functions by default are global and public, you can't change their access to private. That's not the way they are supposed to works because if you change their type to private, you will NEVER be able to access to that function. Also, static doesn't works because is another property of OOP...
Then, you can simply create that function and access it from everywhere you want (obviously where is available :P because you need to include the file where is stored)
I'm coding a Wordpress plugin and I'm not sure regarding the function name conflict..
I have a file named test_handling.php which contains the following content :
function testing() { echo 'test'; }
I included this file in a class constructor (file named testcls.class.php) :
class TestCls {
function __construct() {
require_once('test_handling.php');
testing();
}
function otherfunction() {
testing();
}
// ...
}
In this case, I would like to know if the testing() function is only available in the TestCls class, or can it create conflicts if an other WP plugin has a function with the same name ?
Even with the same name, the functions will have different scope if defined as class method. To make a call to a regular function you will do the following:
testing();
and the result will be:
'test'
the class method need an instance of the class or be statically called. To call the method class you will need the following formats:
$class->test();
or
OtherPlugin::test();
To sum up, the function test will be different if defined as class method. Then, you will not have conflicts.
Other way to encapsulate your function and make sure you are using the right one is with namespaces. If you use a namespace in your test_handling.php
<?php
namespace myname;
function testing(){echo 'test';}
?>
You will access the function test like this:
<?php
require_once "test_handling.php";
use myname;
echo myname\testing();
Now you are sure about the function you are calling.
When a file is included, the code it contains inherits the variable
scope of the line on which the include occurs. Any variables available
at that line in the calling file will be available within the called
file, from that point forward. However, all functions and classes
defined in the included file have the global scope.
from include in PHP manual
Which means that yes, you can have conflicts.
I want create a helper class that containing method like cleanArray, split_char, split_word, etc.
The helper class it self will be used with many class. example :
Class A will user Helper, Class B, Class C, D, E also user Helper Class
what the best way to write and use helper class in PHP ?
what i know is basic knowledge of OOP that in every Class that use Helper class must create a helper object.
$helper = new Helper();
It that right or may be some one can give me best way to do that.
I also will create XXX Class that may use Class A, B, C, etc.
UPDATE : ->FIXED my fault in split_word method :D
Based on Saul, Aram Kocharyan and alex answer, i modified my code, but its dont work, i dont know why.
<?php
class Helper {
static function split_word($text) {
$array = mb_split("\s", preg_replace( "/[^\p{L}|\p{Zs}]/u", " ", $text ));
return $this->clean_array($array);
}
static function split_char($text) {
return preg_split('/(?<!^)(?!$)/u', mb_strtolower(preg_replace( "/[^\p{L}]/u", "", $text )));
}
}
?>
and i use in other Class
<?php
include "Helper.php";
class LanguageDetection {
public function detectLanguage($text) {
$arrayOfChar = Helper::split_char($text);
$words = Helper::split_word($text);
return $arrayOfChar;
}
}
$i = new Detection();
print_r($i->detectLanguage("ab cd UEEef する ح خهعغ فق 12 34 ٢ ٣ .,}{ + _"));
?>
Helper classes are usually a sign of lack of knowledge about the Model's problem domain and considered an AntiPattern (or at least a Code Smell) by many. Move methods where they belong, e.g. on the objects on which properties they operate on, instead of collecting remotely related functions in static classes. Use Inheritance for classes that share the same behavior. Use Composition when objects are behaviorally different but need to share some functionality. Or use Traits.
The static Utils class you will often find in PHP is a code smell. People will throw more or less random functions into a class for organizing them. This is fine when you want to do procedural coding with PHP<5.2. As of 5.3 you would group those into a namespace instead. When you want to do OOP, you want to avoid static methods. You want your objects to have High Cohesion and Low Coupling. Static methods achieve the exact opposite. This will also make your code less testable.
Are Helper Classes Evil?
Killing the Helper class, part two
Functional Decomposition AntiPattern
Is the word "Helper" in a class name a code smell?
Moreover, every Class that use Helper class must create a helper object is a code smell. Your collaborators should not create other collaborators. Move creation of complex object graphs into Factories or Builders instead.
As a rule of thumb, helpers should contain functionality that is common but has no special designation under the overall architecture of the application.
Suffix the classname with Helper
Use static methods whenever possible
In short:
// Helper sample
//
class ConversionHelper {
static function helpThis() {
// code
}
static function helpThat() {
// code
}
}
// Usage sample
//
class User {
function createThings() {
$received = ConversionHelper::helpThis();
}
}
Instead of creating static class , you should just write simple functions , and include that file at the index/bootstrap file (you can even use namespaces with it).
Instead of:
class Helper {
static function split_word($text) { ...
static function split_char($text) { ...
}
It should be:
namespace Helper;
function split_word($text) { ...
function split_char($text) { ...
There is no point wrapping it all up in a class. Just because you put it in a class doesn't make it object oriented .. actually it does the exact oposite.
You could create a class with static methods...
class Str {
public static function split_char($str, $chr) {
...
}
}
You could also namespace a bunch of functions with a namespace, but I think the former is preferred.
Use public static methods in the class as such:
/* Common utility functions mainly for formatting, parsing etc. */
class CrayonUtil {
/* Creates an array of integers based on a given range string of format "int - int"
Eg. range_str('2 - 5'); */
public static function range_str($str) {
preg_match('#(\d+)\s*-\s*(\d+)#', $str, $matches);
if (count($matches) == 3) {
return range($matches[1], $matches[2]);
}
return FALSE;
}
// More here ...
}
Then invoke them like this:
CrayonUtil::range_str('5-6');
If in another file, use the following at the top:
require_once 'the_util_file.php';