defining a class within the function - php

I'm just learning the php and came out a question in my mind, Can I define the class within the function like this:
public class test{
public function newtest(){
// defining a class here like this:
public class funclass{
.....
}
}
}

Yes, you can
function a(){
class A {
}
}
var_dump(class_exists('A')); //bool(false)
a();
var_dump(class_exists('A')); //bool(true)
But, remeber that classes are globals. You cannot bound class to function scope only.

You can not.
Run your code after removing those publics and you ll get this:
Fatal error: Class declarations may not be nested on line 6
Read 1
Read 2

Related

Extending classes in PHP - strange behaviour

First, quote from PHP manual (http://php.net/manual/en/keyword.extends.php):
The extended or derived class has all variables and functions of the
base class (this is called 'inheritance' despite the fact that nobody
died) and what you add in the extended definition.
So why is that this simple example doesn't work:
<?php
class A
{
private function a()
{
echo 'a';
}
public function b()
{
echo 'b';
}
}
class B extends A
{
//no extended definition, only what's inherited
}
$object_B = new B();
echo $object_B->b(); // fatal error: Call to private A::a() from invalid context
?>
After some experimenting, it turns out that removing method a from class A
makes it work. And I'm not even calling it anywhere.
You can use a method of the same name as a constructor with a PHP class. So, your method a is acting as a constructor for class A.
Rename your method, and it should work:
class First
{
private function another()
{
echo 'a';
}
public function b()
{
echo 'b';
}
}
See __construct() vs SameAsClassName() for constructor in PHP
"Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP" - Reports PHP 7 after executing the sample code.
I think you can't name the method with the same name as the class. In older PHP-Versions you could define the constructor of the class by naming the method like the class. PHP assumes the functions a to be a constructor. So it won't work that way.
Like Zac Brown said, you have to use the __construct() method.
In class A you have define a() method it with same name of class. so it is constructor method of A class. but in PHP you can not make private constructor method. your code should be like this.
<?php
class A
{
public function a()
{
echo 'a';
}
public function b()
{
echo 'b';
}
}
class B extends A
{
//no extended definition, only what's inherited
}
$object_B = new B();
echo $object_B->b();
Here's the clarification:
You are defining method a() in Class A. They have the same name so method a() is treated as constructor of Class A. Therefore, the moment you initialize Class B in $object_B = new B();, you initialize Class A too since A is extending B and the constructor method is called. Because Classes which have a constructor method call this method on each newly-created object PHP Constructor. and hence the error.
I believe this clarifies your doubt.

PHP Class extending an Abstract cannot run a function that has the same name as the Abstract Class

This code fails. But I don't understand why. If I change the function lol to function anything else, it works. If I change the class of the Abstract it also works. See this execution: http://codepad.viper-7.com/Z9V67x
<?php
abstract class Lol{
abstract public function lol($external = false);
}
class Crazy extends Lol{
public function lol($external = false){
echo 'lol';
}
}
$new = new Crazy;
$new->lol('fdgdfg');
The error that comes back is:
Fatal error: Cannot call abstract method Lol::lol() in /code/Z9V67x on line 17
PHP Fatal error: Cannot call abstract method Lol::lol() in /code/Z9V67x on line 17
Doing some research on same name functions and classes, in PHP4 the same name meant a constructor. According to this https://stackoverflow.com/a/6872939/582917 answer, namespaced classes no longer treated functions with the same name as the constructor. BUt non namespaced classes do. Still why can't the constructors be replaced in the child instance?
check code below:
abstract class Lol{
public function __construct() { // only one constructor is really needed
}
abstract public function lol($external = false);
}
class Crazy extends Lol{
public function __construct() { // only one constructor is really needed
}
public function Crazy() { // only one constructor is really needed
}
public function lol($external = false) {
echo 'lol';
}
}
$new = new Crazy();
$new->lol('fdgdfg');
it works ok, why?
PHP is not very good with OOP, even latest version, it has PHP4 legacy, so lets try to understand what your code do:
it defined abstract function, which is understand by php as constructor and as abstract method
in sub class you're defining only method, but constructor is still abstract
this is why you're getting error during new - php really cannot find constructor
now check code above - it has 3 constructors, you can have any 1 and this code will work

php multiple classes and methods with same name

If I call "myClass::getItems()" from the "workingCLass" which getId method will be called? The one that echos "hello" or "bye"? Thank you.
class myClass extends otherClass {
function getId(){
echo "hello";
}
}
class otherClass{
function getItems(){
$this->getId();
}
function getId(){
echo "bye";
}
}
class workingClass extends myClass {
function __construct(){
$this->getItems();
}
}
The one with "hello", because you explicitly specified which one to call.
The problem, though, is that it's not static and you call it in a static context.
EDIT: With $this, it will not call anything, because there's no getItems() in the workingClass. If workingClass extended the otherClass it would do the "bye" thingie.
This will result in fatal error, since you are calling this method statically (::) and inside this method you are using $this special variable, that refers to workingClass(object from which it was called) and workingClass has no getId method.
OK, now after fixing the example I can say that it will output 'hello', because when calling method from the object ($this->) PHP will always run one defined in latest child class.

require_once() in a class

I noticed that if I declare a function inside a class method that has the same name as a outside function I get a error:
function a(){
...
}
class foo{
public function init(){
function a(){ // <- error
...
}
...
}
}
this however would work:
function a(){
...
}
class foo{
public static function a(){
...
}
}
Can I include a set of functions that act as static methods for this class using require_once or something like that?
require_once('file.php'); after class foo{ doesn't work...
PHP allows to nest function declarations in others, but it doesn't actually have nested functions. They always end up in the global scope. So the a() that you define in your init method clashes with the already defined function a().
The static function a() is associated with the class namespace, even if it behaves like a function, not a method.
Invoking a require_once statement in a class definition is not possible. The PHP syntax does not allow for it. Class definitions are special scopes / language constructs, that only allow function or variable declarations within the immediate parsing level. - So PHP does not allow for that (classes and their methods must be declared at once, not assembled), and there are no really nice or advisable workarounds for what you want.
If your class structure allows, you can split the class into several different classes which are part of an inheritance chain:
class foo1 {
public static function a() {}
}
class foo extends foo1 {
public static function b() {}
}
Alternatively, you can use __callStatic() if you are willing to take the performance hit. (Requires PHP 5.3; though if you only need non-static methods, __call is available from 5.0.) Smarty 3 does this IIRC.
class foo {
private static $parts = array('A', 'B');
public static __callStatic($name, $arguments) {
foreach (self::$parts as $part) {
if (method_exists($part, $name)) {
return call_user_func_array(array($part, $name), $arguments);
}
}
throw new Exception();
}
}
class A {
public static function a() {}
}
class B {
public static function b() {}
}
PHP 5.4 will supposedly include traits, which are a more straightforward way of including external code in a class:
class foo {
use A, B;
}
trait A {
public static function a() {}
}
trait B {
public static function b() {}
}
To answer the question: you should first check whether or not the function a has already been implemented by using function_exists:
class foo{
public function init(){
if(!function_exists('a')):
function a(){ // <- will only be declared when it doesn't already exist
...
}
endif;
...
}
}
However, consider this as a very bad coding practice. It will get a mess pretty soon as you have no idea of what's going on exactly and what function will be used. I'd say you'd be better off using a subclass and require_once the appropriate subclass.
Assuming not defining the second "a" method is not acceptable, you'll need to move it outside the init method.
It sounds like your require_once call is the problem (definitely should not be called inside the class). Could you post a full sample including your require_once call that isn't working ?

call a static method inside a class?

how do i call a static method from another method inside the same class?
$this->staticMethod();
or
$this::staticMethod();
self::staticMethod();
More information about the Static keyword.
Let's assume this is your class:
class Test
{
private $baz = 1;
public function foo() { ... }
public function bar()
{
printf("baz = %d\n", $this->baz);
}
public static function staticMethod() { echo "static method\n"; }
}
From within the foo() method, let's look at the different options:
$this->staticMethod();
So that calls staticMethod() as an instance method, right? It does not. This is because the method is declared as public static the interpreter will call it as a static method, so it will work as expected. It could be argued that doing so makes it less obvious from the code that a static method call is taking place.
$this::staticMethod();
Since PHP 5.3 you can use $var::method() to mean <class-of-$var>::; this is quite convenient, though the above use-case is still quite unconventional. So that brings us to the most common way of calling a static method:
self::staticMethod();
Now, before you start thinking that the :: is the static call operator, let me give you another example:
self::bar();
This will print baz = 1, which means that $this->bar() and self::bar() do exactly the same thing; that's because :: is just a scope resolution operator. It's there to make parent::, self:: and static:: work and give you access to static variables; how a method is called depends on its signature and how the caller was called.
To see all of this in action, see this 3v4l.org output.
This is a very late response, but adds some detail on the previous answers
When it comes to calling static methods in PHP from another static method on the same class, it is important to differentiate between self and the class name.
Take for instance this code:
class static_test_class {
public static function test() {
echo "Original class\n";
}
public static function run($use_self) {
if($use_self) {
self::test();
} else {
$class = get_called_class();
$class::test();
}
}
}
class extended_static_test_class extends static_test_class {
public static function test() {
echo "Extended class\n";
}
}
extended_static_test_class::run(true);
extended_static_test_class::run(false);
The output of this code is:
Original class
Extended class
This is because self refers to the class the code is in, rather than the class of the code it is being called from.
If you want to use a method defined on a class which inherits the original class, you need to use something like:
$class = get_called_class();
$class::function_name();
In the later PHP version self::staticMethod(); also will not work. It will throw the strict standard error.
In this case, we can create object of same class and call by object
here is the example
class Foo {
public function fun1() {
echo 'non-static';
}
public static function fun2() {
echo (new self)->fun1();
}
}
call a static method inside a class
className::staticFunctionName
example
ClassName::staticMethod();

Categories