-3

I tried to make a function inside a function:

<?php
class usermanager extends datamanager {

public $id;
public $name;
public $from;
public $twitter;
public $instagram;
public $skype;

public $regIP;
public $lastIP;
public $email;

public function __construct($exists = false,$uid = 0) {

if ($exists == true) {
$this->id = $uid;
$this->name = $this->fetch("SELECT * FROM users WHERE ID = '".$uid."';")->name;

public function getProfile() {
profile();
}

}

else {

public function new($name,$password,$email) {

$this->autocommit(false);
if (!($do = $this->query("INSERT INTO users (name,password,email,rank) VALUES ('".$name."',PASSWORD('".$password."'),'".$email."','0');"))) {
$this->rollback();
return false;
}
else {
$this->commit();
return true;
}

} //end new()

} //end else

} //end __construct()

public function __set() {

trigger_error("Can not edit read-only variable",E_USER_ERROR);

} //end __set()

private function profile() {

$gets = array("twitter","instagram","skype","from");

$fetch = $this->fetch("SELECT * FROM users WHERE ID = '".$this->id."';");
foreach ($gets as $get) {
$this->$get = $fetch->$get;
}

}

} //end class
?>

Because I saw this I thought it would work, but I got:

Parse error: syntax error, unexpected T_PUBLIC in /home/a7405987/usermanager.php on line 21

Why doesn't this work?


It is fixed now, but now I'm getting another error:

Call to undefined function getProfile()

How can I fix this?

Community
  • 1
  • 1
  • line 21 which is? `public function new`? – rray Mar 29 '16 at 13:52
  • Hmm, yeah, well, functions inside functions is not really a thing that exists in PHP. – deceze Mar 29 '16 at 13:53
  • @deceze - Yes it is: http://stackoverflow.com/q/415969/477563 – Mr. Llama Mar 29 '16 at 13:54
  • 1
    @Mr.Llama First sentence of accepted answer: *"There is none basically, I've always treated this as a side effect of the parser."* – ***Yes***, you *can* write functions inside functions and that actually does something, but it probably doesn't do what OP thinks it does, and it most certainly doesn't work the way OP wants it to work. – deceze Mar 29 '16 at 13:56
  • @rray to make a new user and add him/her to the database – Björn Schönrock Mar 29 '16 at 13:56
  • 1
    `new` is a reserved keyword in PHP. You can't create a function with that name. – Devon Bessemer Mar 29 '16 at 13:56
  • @Devon Woops... I'll change that – Björn Schönrock Mar 29 '16 at 14:02
  • 1
    @BjörnSchönrock - Your edit (the new problem about mysqloi) should be a new question. – Mr. Llama Mar 29 '16 at 15:18
  • @Mr.Llama I can't ask new questions for some reason... It says I've asked 5 questions and I have to take a break. But I didn't even ask 5, I asked 4 questions. – Björn Schönrock Mar 29 '16 at 15:36
  • @BjörnSchönrock - New users (those with low reputation) have certain limitations. Consider participating in the community to raise your reputation some, then your account will be less limited. Try answering questions or even something as simple as voting on questions can help you build reputation. – Mr. Llama Mar 29 '16 at 16:20
  • I can't even vote as I don't have enough reputation because some questions got voted down. – Björn Schönrock Mar 29 '16 at 17:25

2 Answers2

3

Defining a function within a function isn't a great idea. Aside from classes, any function definitions are automatically global. The public and private keywords are only valid in a class definition, not within a class function. If you were to remove the public from your inner function definition, it would run without error, but the result would be a globally defined getProfile().

This example should help demonstate the issue:

<?php

class Test {
    public function foo() {
        function bar() {
            echo "Hello from bar!" . PHP_EOL;
        }

        echo "Hello from foo!" . PHP_EOL;
    }
}

$t = new Test;
// PHP Fatal error:  Call to undefined method Test::bar()
// $t->bar();

// Works, prints "Hello from foo!"
// bar() is now defined, but not where you expect
$t->foo();

// PHP Fatal error:  Call to undefined method Test::bar()
// $t->bar();

// Works, prints "Hello from bar!"
// Note that this is global scope, not from Test
bar();

Demo in action

Community
  • 1
  • 1
Mr. Llama
  • 20,202
  • 2
  • 62
  • 115
2

You cannot use modifiers public/private/protected inside a member function or here a constructor. You can however declare a function inside a method :

public function classMember() {
    function doSomething() {
    //do something
    }
    doSomething()
}

For your particular problem, you should instanciate your class and then check if it exists, otherwise insert it.

You cannot change the structure of a class depending on the context it is called

n00dl3
  • 21,213
  • 7
  • 66
  • 76
  • If I make a new usermanager() and I want to get an existing user from the database I can use usermanager(true,$id); but the function getProfile() must only exist if I use an existing user. – Björn Schönrock Mar 29 '16 at 13:59
  • But my question is, why do I get this error? – Björn Schönrock Mar 29 '16 at 14:01
  • The way to do that is to make getProfile throw an exception if it's called without an existing user. You get the error because you're trying to do something that the syntax of the language doesn't allow. It's like trying to speak to an Indian in Chinese. Doesn't work. – Gralgrathor Mar 29 '16 at 14:01
  • then you are not thinking the problem correctly, you should instanciate your class and THEN, insert it or not from the code that uses it. – n00dl3 Mar 29 '16 at 14:01
  • the answer is "because it is not allowed". – n00dl3 Mar 29 '16 at 14:03
  • Why is http://stackoverflow.com/questions/1631535/function-inside-a-function working then? – Björn Schönrock Mar 29 '16 at 14:11
  • because he's not using public/private/protected modifiers – n00dl3 Mar 29 '16 at 14:11
  • those keywords have no sense outside of a class declaration, here you are not in a class declaration but in a method, so it's a non-sense for the interpreter. – n00dl3 Mar 29 '16 at 14:13
  • There's enumerations, isn't there? Couldn't you have a conditional class structure based on enumerations? (I'm a bit vague on the newer features of PHP - everything after PHP3, I mean - so I might be completely off) – Gralgrathor Mar 29 '16 at 14:20
  • I don't understand what you mean, but it is definitely not possible to alter the structure of the class while instanciating it or calling member functions – n00dl3 Mar 29 '16 at 14:23
  • I was probably confusing this stuff with Java. You can always use a cast, of course. – Gralgrathor Mar 30 '16 at 07:07