Static Method/Function of Class in PHP - php

I trying to use static method (I do not want to instantiate a class).
and I put this example.
<?php
class RootClass {
const Member = 20;
public static function Member() {
return self::Member;
}
}
class NewClass {
private $ValNewClass = "";
private function InitNewClass() {
$this->ValNewClass = RootClass::Member();
}
public static function GetNewVal() {
$this->InitNewClass();
$Validation = true;
if ($this->ValNewClass>10){
echo "greater than 10";
$Validation = false;
} else {
echo "Not greater than 10";
}
return $Validation;
}
}
$Val2 = NewClass::GetNewVal(); //It must print "greater than 10"
?>
I need to know where is my mistakes.
This is not real code, only is simple form for ask.
Thank you.

In PHP the $this variable is not available inside a method declared as static.

You can't refer to non-static fields, inside your static method. Values inside this kind of classess cannot be object-dependent. When you use $this->field, you're refering to the value inside an instance of the class. If you want to modify static field, you should use self::field.

<?php
class Rootclass {
const MEMBER = 20;
public static function member() {
return self::MEMBER;
}
}
class Newclass {
private static $valnewclass = "";
private function initnewclass() {
self::$valnewclass = Rootclass::member();
}
public static function getnewval() {
self::initnewclass(); //Initialice Val for make comparation
$validation = true;
if (self::$valnewclass>10){
echo "<br>greater than 10";
$Validation = false;
} else {
echo "<br>Not greater than 10";
}
return $validation;
}
}
$Val2 = Newclass::getnewval(); //It must print "greater than 10"
echo "<br>After";
?>
Thank you
The code is working.
Chepe.

Related

Assign property value using an anonymous function

My class is like this:
<?php
class ExampleClass{
private $example_property = false;
public function __construct(){
$this->example_property = function() {
$this->example_property = 1;
return $this->example_property;
};
}
public function get_example_property(){
return $this->example_property;
}
}
$example = new ExampleClass();
echo $example->get_example_property();
Property $example_property must be false until you call it, then, the first time it is called, I want to assign 1 to it. What's wrong with my code?
Error: Error Object of class Closure could not be converted to string on line number 20.
I just tried to play a little bit with your code.
To make it possible, you'll have to find out, whether your variable is a function (defined in your __construct) or the number set by this function
<?php
class ExampleClass{
private $example_property = false;
public function __construct(){
$this->example_property = function() {
$this->example_property = 1;
return $this->example_property;
};
}
public function get_example_property(){
$func = $this->example_property;
if(is_object($func) && get_class($func)=='Closure'){
return $func();
}
return $func;
}
}
$example = new ExampleClass();
echo $example->get_example_property(); //returning 1
echo $example->get_example_property(); //returning 1 again
But anyway, I don't see any sense in doing this.
The typical solution would be something like this:
class ExampleClass{
private $example_property = false;
public function __construct(){
//usually initializing properties goes here.
//$this->example_property = 1;
}
public function get_example_property(){
// I think you want a value to be initialzed only if needed.
// so then it can go here.
if(!$this->example_property) {
$this->example_property = 1; //initialize it, if needed
}
return $this->example_property;
}
}
$example = new ExampleClass();
echo $example->get_example_property(); //returning 1
echo $example->get_example_property(); //returning 1 again

PHP how set default value to a variable in the class?

class A{
public $name;
public function __construct() {
$this->name = 'first';
}
public function test1(){
if(!empty($_POST["name"]))
{
$name = 'second';
}
echo $name;
}
$f = new A;
$f->test1();
Why don't we get first and how set right default value variable $name only for class A?
I would be grateful for any help.
You can use a constructor to set the initial values (or pretty much do anything for that matter) as you need to like this:
class example
{
public $name;
public function __construct()
{
$this->name="first";
}
}
Then you can use these default values in your other functions.
class example
{
public $name;
public function __construct()
{
$this->name="first";
}
public function test1($inputName)
{
if(!empty($inputName))
{
$this->name=$inputName;
}
echo "The name is ".$this->name."\r\n";
}
}
$ex=new example();
$ex->test1(" "); // prints first.
$ex->test1("Bobby"); // prints Bobby
$ex->test1($_POST["name"]); // works as you expected it to.
you have two options to set the default values for the class attributes:
Option 1: set at the parameter level.
class A
{
public $name = "first";
public function test1()
{
echo $this->name;
}
}
$f = new A();
$f->test1();
Option 2: the magic method __construct() always being executed each time that you create a new instance.
class A
{
public $name;
public function __construct()
{
$this->name = 'first';
}
public function test1()
{
echo $this->name;
}
}
$f = new A();
$f->test1();
Use isset() to assign a default to a variable that may already have a value:
if (! isset($cars)) {
$cars = $default_cars;
}
Use the ternary (a ? b : c) operator to give a new variable a (possibly default) value:
$cars = isset($_GET['cars']) ? $_GET['cars'] : $default_cars;

Switch visibility in php if parameter

I'm wondering if its possible to switch the visibility in PHP. Let me demonstrate:
class One {
function __construct($id){
if(is_numeric($id)){
//Test function becomes public instead of private.
}
}
private function test(){
//This is a private function but if $id is numeric this is a public function
}
}
Is such thing even possible?
I would use an abstract class with two implementing classes: One for numeric and one for non-numeric:
abstract class One {
static function generate($id) {
return is_numeric($id) ? new OneNumeric($id) : new OneNonNumeric($id);
}
private function __construct($id) {
$this->id = $id;
}
}
class OneNumeric extends One {
private function test() {
}
}
class OneNonNumeric extends One {
public function test() {
}
}
$numeric = One::generate(5);
$non_numeric = One::generate('not a number');
$non_numeric->test(); //works
$numeric->test(); //fatal error
It can be faked up to a point with magic methods:
<?php
class One {
private $test_is_public = false;
function __construct($id){
if(is_numeric($id)){
$this->test_is_public = true;
}
}
private function test(){
echo "test() was called\n";
}
public function __call($name, $arguments){
if( $name=='test' && $this->test_is_public ){
return $this->test();
}else{
throw new LogicException("Method $name() does not exist or is not public\n");
}
}
}
echo "Test should be public:\n";
$numeric = new One('123e20');
$numeric->test();
echo "Test should be private:\n";
$non_numeric = new One('foo');
$non_numeric->test();
I haven't thought about the side effects. Probably, it's only useful as mere proof of concept.

Pass variables from class instance to its extended method

I'm trying to pass a variable to a method in an extended class, but it's not working.
Here's the sample code:
class set2 extends set1
{
function Body($variable) {
}
}
$start2 = new set2();
$start2->Body('some text');
The last line is the part I'm trying to get to work. I'm not sure if I should have a constructor instead to do it or how it's best to get it to work.
I figured it out. I just added a public variable instead and passed its value like this:
class set2 extends set1
{
public $variable = NULL;
function Body() {
echo $this->variable;
}
}
$start2 = new set2();
$start2->variable = 'Some Text';
Three different ways of doing what I think you're trying to do:
class set1
{
protected $headVariable;
function Head() {
echo $this->headVariable;
}
function Body($variable) {
echo $variable;
}
function Foot() {
echo static::$footVariable;
}
}
class set2 extends set1
{
protected static $footVariable;
function Head($variable) {
$this->headVariable = $variable;
parent::Head();
}
function Body($variable) {
parent::Body($variable);
}
function Foot($variable) {
self::$footVariable = $variable;
parent::Foot();
}
}
$start2 = new set2();
$start2->Head('some text');
$start2->Body('some more text');
$start2->Foot('yet more text');

PHP: How do I check if all public methods of two classes return the same values?

In effect, if I have a class c and instances of $c1 and $c2
which might have different private variable amounts but all their public methods return the same values I would like to be able to check that $c1 == $c2?
Does anyone know an easy way to do this?
You can also implement a equal($other) function like
<?php
class Foo {
public function equals($o) {
return ($o instanceof 'Foo') && $o.firstName()==$this.firstName();
}
}
or use foreach to iterate over the public properties (this behaviour might be overwritten) of one object and compare them to the other object's properties.
<?php
function equalsInSomeWay($a, $b) {
if ( !($b instanceof $a) ) {
return false;
}
foreach($a as $name=>$value) {
if ( !isset($b->$name) || $b->$name!=$value ) {
return false;
}
}
return true;
}
(untested)
or (more or less) the same using the Reflection classes, see http://php.net/manual/en/language.oop5.reflection.php#language.oop5.reflection.reflectionobject
With reflection you might also implement a more duck-typing kind of comparision, if you want to, like "I don't care if it's an instance of or the same class as long as it has the same public methods and they return the 'same' values"
it really depends on how you define "equal".
It's difficult to follow exactly what you're after. Your question seems to imply that these public methods don't require arguments, or that if they did they would be the same arguments.
You could probably get quite far using the inbuilt reflection classes.
Pasted below is a quick test I knocked up to compare the returns of all the public methods of two classes and ensure they were they same. You could easily modify it to ignore non matching public methods (i.e. only check for equality on public methods in class2 which exist in class1). Giving a set of arguments to pass in would be trickier - but could be done with an array of methods names / arguments to call against each class.
Anyway, this may have some bits in it which could be of use to you.
$class1 = new Class1();
$class2 = new Class2();
$class3 = new Class3();
$class4 = new Class4();
$class5 = new Class5();
echo ClassChecker::samePublicMethods($class1,$class2); //should be true
echo ClassChecker::samePublicMethods($class1,$class3); //should be false - different values
echo ClassChecker::samePublicMethods($class1,$class4); //should be false -- class3 contains extra public methods
echo ClassChecker::samePublicMethods($class1,$class5); //should be true -- class5 contains extra private methods
class ClassChecker {
public static function samePublicMethods($class1, $class2) {
$class1methods = array();
$r = new ReflectionClass($class1);
$methods = $r->getMethods();
foreach($methods as $m) {
if ($m->isPublic()) {
#$result = call_user_method($m->getName(), $class1);
$class1methods[$m->getName()] = $result;
}
}
$r = new ReflectionClass($class2);
$methods = $r->getMethods();
foreach($methods as $m) {
//only comparing public methods
if ($m->isPublic()) {
//public method doesn't match method in class1 so return false
if(!isset($class1methods[$m->getName()])) {
return false;
}
//public method of same name doesn't return same value so return false
#$result = call_user_method($m->getName(), $class2);
if ($class1methods[$m->getName()] !== $result) {
return false;
}
}
}
return true;
}
}
class Class1 {
private $b = 'bbb';
public function one() {
return 999;
}
public function two() {
return "bendy";
}
}
class Class2 {
private $a = 'aaa';
public function one() {
return 999;
}
public function two() {
return "bendy";
}
}
class Class3 {
private $c = 'ccc';
public function one() {
return 222;
}
public function two() {
return "bendy";
}
}
class Class4 {
public function one() {
return 999;
}
public function two() {
return "bendy";
}
public function three() {
return true;
}
}
class Class5 {
public function one() {
return 999;
}
public function two() {
return "bendy";
}
private function three() {
return true;
}
}
You can define PHP's __toString magic method inside your class.
For example
class cat {
private $name;
public function __contruct($catname) {
$this->name = $catname;
}
public function __toString() {
return "My name is " . $this->name . "\n";
}
}
$max = new cat('max');
$toby = new cat('toby');
print $max; // echoes 'My name is max'
print $toby; // echoes 'My name is toby'
if($max == $toby) {
echo 'Woohoo!\n';
} else {
echo 'Doh!\n';
}
Then you can use the equality operator to check if both instances are equal or not.
HTH,
Rushi
George: You may have already seen this but it may help: http://usphp.com/manual/en/language.oop5.object-comparison.php
When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values, and are instances of the same class.
They don't get implicitly converted to strings.
If you want todo comparison, you will end up modifying your classes. You can also write some method of your own todo comparison using getters & setters
You can try writing a class of your own to plugin and write methods that do comparison based on what you define. For example:
class Validate {
public function validateName($c1, $c2) {
if($c1->FirstName == "foo" && $c2->LastName == "foo") {
return true;
} else if (// someother condition) {
return // someval;
} else {
return false;
}
}
public function validatePhoneNumber($c1, $c2) {
// some code
}
}
This will probably be the only way where you wont have to modify the pre-existing class code

Categories