5
Before questions or criticisms arise about not being able to do this simply because the methods static not having access to variables and public methods, private and protected, because they are accessible even without an instance of the class, I only say that, I already know this.
It happens that at the moment it starts to bother me a bit the simple fact of always having to instantiate a new class using the "keyword" new all the time, because sometimes I’m forced to function like this.
Let’s see, in this for example:
<?php
class Teste {
const EU = "<b>Disse ele:</b>\n";
public function eu(){
return self::EU . $this->ele();
}
private function ele(){
return 'Pertenço a 3º pessoa';
}
}
$teste = new Teste();
print $teste->eu();
?>
The first method is only public, and has access to both public, private, and class protected properties and methods without any problems.
Next we have this:
class Teste1 {
const EU = "<b>Disse ele:</b>\n";
public static function eu(){
return self::EU . $this->ele();
}
private function ele(){
return 'Pertenço à 3º pessoa';
}
}
print Teste1::eu();
What this will return is already obvious:
Fatal error: Using $this when not in Object context in ...
Doing this:
<?php
class Teste1 {
static $instance;
const EU = "<b>Disse ele:</b>\n";
public static function get(){
if(empty(self::$instance)):
self::$instance = new Teste1();
endif;
return self::$instance;
}
public static function eu(){
return self::EU . self::$instance->ele();
}
private function ele(){
return 'Pertenço à 3º pessoa';
}
}
print Teste1::get()->eu();
?>
The situation can be circumvented, that is, it is not circumvented, since an instance is created using the "keyword" new
, but it works, and automates the rest. The examples I’ve just given may not explain exactly why I need to avoid using the new
, but perhaps these two examples here explain.
The only reason I want this, is that in my classes, not all methods are/should be accessible even with an instance of this class, because they are only complementary methods/articulations to the static methods I am creating, and in a class with about 10 methods, only 3 of them are accessible, and the type of access I want for this average of 3 methods, is direct access without any prior instance.
1st Example - The expected:
<?php
class Hash {
static $hash;
const COST = "$2y$10$";
public static function hash_create($password){
return crypt($password, $this->salt(self::COST)); # <--- $this
}
public static function hash_verify($password, $db_hash){
$hash = crypt($password, $db_hash);
return $this->are_equal($hash, $db_hash); # <--- $this
}
// métodos projectados apenas para uso interno
private function random(){
return md5(uniqid(), true);
}
private function fix_random($random){
$encode = base64_encode($random);
return str_replace("+", ".", $encode);
}
private function half_salt($size=null){
$size = empty($size) ? 22 : $size;
return substr($this->fix_random($this->random()), 0, $size);
}
private function salt($cost){
return $cost.$this->half_salt();
}
private function are_equal($x, $y){
if($x === $y):
return true;
else:
return false;
endif;
}
}
## 3º Método - PRETENDIDO (nada será executado) ##
print Hash::hash_create('password');
print "<br/>";
$db_hash = Hash::hash_create('password');
var_dump(Hash::hash_verify('password', $db_hash)); # (null);
?>
2nd Example - The trail (forced):
<?php
class Hash {
static $hash;
const COST = "$2y$10$";
# 1º notação
public function create($password){
return crypt($password, $this->salt(self::COST));
}
public function verify($password, $db_hash){
$hash = crypt($password, $db_hash);
return $this->are_equal($hash, $db_hash);
}
// métodos projectados apenas para uso interno
private function random(){
return md5(uniqid(), true);
}
private function fix_random($random){
$encode = base64_encode($random);
return str_replace("+", ".", $encode);
}
private function half_salt($size=null){
$size = empty($size) ? 22 : $size;
return substr($this->fix_random($this->random()), 0, $size);
}
private function salt($cost){
return $cost.$this->half_salt();
}
private function are_equal($x, $y){
if($x === $y):
return true;
else:
return false;
endif;
}
}
## 1º Método - NORMAL ##
$hash = new Hash(); # <---
print $hash->create('password');
print "<br/>";
$db_hash = $hash->create('password');
var_dump($hash->verify('password', $db_hash)); # (true);
?>
This above, although it works, does exactly what I want to avoid, yet it is the right way.
3rd Example - HACK (The solution I found)
<?php
class Hash {
static $hash;
const COST = "$2y$10$";
public static function instance(){
if(empty(self::$hash)){
self::$hash = $self = new Hash();
}
return self::$hash;
}
# 2º notação
public static function hash_create($password){
return crypt($password, self::$hash->salt(self::COST));
}
public static function hash_verify($password, $db_hash){
$hash = crypt($password, $db_hash);
return self::$hash->are_equal($hash, $db_hash);
}
// métodos projectados apenas para uso interno
private function random(){
return md5(uniqid(), true);
}
private function fix_random($random){
$encode = base64_encode($random);
return str_replace("+", ".", $encode);
}
private function half_salt($size=null){
$size = empty($size) ? 22 : $size;
return substr($this->fix_random($this->random()), 0, $size);
}
private function salt($cost){
return $cost.$this->half_salt();
}
private function are_equal($x, $y){
if($x === $y):
return true;
else:
return false;
endif;
}
}
## 2º Método - HACK ##
print Hash::instance()->hash_create('password');
print "<br/>";
$db_hash = Hash::hash_create('password');
var_dump(Hash::hash_verify('password', $db_hash)); # (true);
?>
Even though it works, and basically give me what I want, hacks are not exactly my strong suit, and I worry too much about good practice. Once this solution is adopted, what evils am I forgetting? Is it really acceptable ? I mean, because sometimes in creating a solution we also create new problems.
Opa Laravel :D +1
– rray
Okay, thanks for the feedback, but on a first impression, it’s not exactly the intended, I just want to avoid using the new as also want to extinguish any access through it, thereby also avoiding public methods.
– Edilson
Another brief explanation is that I’ve never worked with frameworks, so I don’t know much of the terms used in them, I can understand the type of construction and methods, but I have problems with terms, I will do ,the searches to see if I can clear some dependencies.
– Edilson
@Edilson,
Facade
is facade. Something false. It is a facade class to have easy access of other– Wallace Maxters
Ah, I did it yesterday, while creating the examples, I preferred not to add to that because I found irrelevant to the main situation, I anyway dispensed with the use of it by creating more methods, and by simply creating public access in private and protected methods, through new. However the example you showed seems to have a different approach. I will do tests, and I appreciate the explanation.
– Edilson