I have a php project that uses some functional elements, and some OOP elements, but it seems mixing the two is causing problems. Here are the files that are causing the errors:
DB.php
<?php
function parse_db_entry($from, &$to){
//Function code here
}
?>
User.php
<?php
require_once 'DB.php';
class User{
//Properties
public function __construct(){
//ctor
}
public static function load_user($email, $password){
$entry = //Make MySQL Request
$user = new User();
parse_db_entry($entry, $user);
return $user;
}
}
?>
Everything works as it should, except the call to parse_db_entry which throws:
Fatal error: Call to undefined function parse_db_entry()
I am able to access other things in DB.php, for instance if I made a class it there I am able to instantiate it without error, and if I move the function into User.php, it is functional as well. So what am I doing wrong? Why can't I call this method?
I've figured it out! Thanks to everyone who had ideas, but it seems the problem was something else.
When calling require_once 'DB.php', php was actually getting the file:
C:\xampp\php\pear\DB.php
instead of mine.
This may be a problem exclusive to XAMPP, but a simple rename of my file to DBUtil.php fixed everything.
This is a stretch, and I'm totally taking a shot in the dark here, but...
Are you sure parse_db_entry is in the global or User's namespace?
Note: I added a few lines here and there for testing/debugging.
DB.php:
<?php
namespace anotherWorld; // added this ns for illustrative purposes
function parse_db_entry($from, &$to){
echo 'called it';
}
?>
User.php:
<?php
namespace helloWorld; // added this ns for illustrative purposes
class User {
//Properties
public function __construct(){
//ctor
}
public static function load_user($email, $password){
$entry = //Make MySQL Request
$user = new User();
parse_db_entry($entry, $user);
return $user;
}
}
?>
test.php:
<?php
require_once 'DB.php';
require_once 'User.php';
use helloWorld\User;
$a = new User();
$a->load_user('email','pass');
echo 'complete';
?>
Yields Fatal error: Call to undefined function helloWorld\parse_db_entry() in User.php on line 13, however when removing the NS declaration in DB.php (namespace anotherWorld) thereby putting parse_db_entry in global NS it runs just fine.
To verify, use the __NAMESPACE__ constant.
If namespace is a problem, without compromising DB's namespace, here is an updated User.php:
<?php
namespace helloWorld;
use anotherWorld; // bring in the other NS
class User {
//Properties
public function __construct(){
//ctor
}
public static function load_user($email, $password){
$entry = //Make MySQL Request
$user = new User();
anotherWorld\parse_db_entry($entry, $user); // call the method from that NS
return $user;
}
}
?>
Related
I'm learning PHP OOP and right now I built a basic calculator.
Here is my code at index.php:
require_once 'Calculator.class.php';
require_once 'Adder.class.php';
require_once 'Substract.class.php';
require_once 'Operator.interface.php';
require_once 'Multiplier.class.php';
require_once 'Devider.class.php';
$c = new Calculator;
$c->setOperation(new Adder);
$c->calculate(10,50); // 60
echo $c->getResult();
And this is the Calculator class file:
class Calculator
{
protected $result;
protected $operation;
public function setOperation(OperatorInterface $operation)
{
$this->operation = $operation;
// var_dump($operation);
}
public function calculate()
{
foreach(func_get_args() as $number)
{
$this->result = $this->operation->run($number,$this->result);
}
}
public function getResult()
{
return $this->result;
}
}
And this is the interface that is being called within this class file:
interface OperatorInterface
{
public function run($number,$result);
}
And this is the class Adder which is called from the index.php:
class Adder implements OperatorInterface
{
public function run($number,$result)
{
return $result + $number;
}
}
As you can see it looks nice and okay... however I get this weird error:
Fatal error: Interface 'OperatorInterface' not found on line 2 Adder.php
So line 2 of Adder Class is this:
class Adder implements OperatorInterface
Which means I have not include the interface properly. But I did include that.
So why am I getting this error?
Where did I make my mistake?
You need to include the Operator.interface.php file before the Adder.class.php file, otherwise when the compiler gets to the Adder class, it hasn't yet encountered anything called OperatorInterface, so it doesn't recognise it and can't verify that it's valid to declare that the Adder class implements it. Since it's also referenced in the Calculator class, you should include it before that as well.
require_once 'Operator.interface.php';
require_once 'Calculator.class.php';
require_once 'Adder.class.php';
require_once 'Substract.class.php';
require_once 'Multiplier.class.php';
require_once 'Devider.class.php';
It should be that simple - for future reference you should always order your includes so that dependencies between them can be satisfied, because they get processed in the order you supply them.
Alright I have a few classes and I'm wanting to pass on an initiated class object but I keep getting errors. It'll work one time, then other times I'll get a
PHP Fatal error: Cannot redeclare class
I don't know what I'm doing wrong. I'm basically trying to clean up my code because I'm ALWAYS having 2-3 includes for every one of my pages. I'd rather just include one class and pass on or use the other classes instances from there. Here's an example of what I have now:
Manage.php - Main Class
<?php
include_once('/path/to/DB.php');
class Manage {
public $db;
public function __construct() {
$this->db = new DB($host,$dbName,$user,$pass);
//other constructor stuff
}
//other functions
}
DB.php - Helper Class
<?php
class DB {
public $conn;
public function __construct($host = false, $db = false, $user = false, $pass = false) {
//connect to database
}
//functions for interacting with the database (get,query,update,insert, etc)
}
UseOfClass.php - Shows how I'd like to use it
<?php
include('/path/to/Manage.php');
$manage = new Manage();
$results = $manage->db->get('table_name');
print_r($results);
Hello i looking for a way to call class function from another class.
i've tried diffrent PHP ways such as the classic way, to call class from class.
http://pastebin.com/X5VfaChr
require_once "user.php";
$user = new UserAction();
class htmloutput{
public function WebSite(){
$user->Moshe();
}
}
Its shows me this error:" syntax error, unexpected 'new' (T_NEW), expecting function (T_FUNCTION)" i dont know about more ways to call a class.
I'll be happy to get helping and
learn somethin' from that.
Have Good day,
Baruch
Besides the comment from Abhik Chakraborty, this fixes the issue coming next:
It's all about scope. Google for DI injection:
require_once "user.php";
$user = new UserAction();
class htmloutput {
public function WebSite(UserAction $user) {
$user->Moshe();
}
}
Try to get the instance inside your function, as the following:
require_once 'user.php';
class htmloutput {
public function WebSite(){
$user = new UserAction();
$user->Moshe();
}
}
To begin, here is the flow so you can understand the problem. I have four files, three of these are classes, I use two namespaces.
login.php is a form, when the form is submited, it comes back to itself and the code below is executed. The login.php calls the Zcrypt::Decrypt and Zcrypt::Encrypt with out issues. the Login::DoLogin(); is also called inside the login.php file.
In the Login.class.php (where DoLogin lives) file I create a new instance of DB, and can call Zcrypt::Decrypt with out error. In Login.class.php I call dbConnect();
In the DB.class.php (where dbConnect lives) file I am unable to call Zcrypt::Decrypt. It gives me a syntax error or that it can not find Zcrypt. I have tried Zcrypt::Decrypt([string]), \Zcrypt::Decrypt([string]), and even \Zcrypt::Decrypt([string]).
The question is, how come I can call Zcrypt in some classes but not others? Im I missing some code for this to work?
Here are my files
login.php:
require 'NS/helpdesk/Login.class.php';
require 'NS/helpdesk/Cryptv2.class.php';
require 'NS/helpdesk/DB.class.php';
use \net\[domain]\Zcrypt;
use \net\[domain]\helpdesk\Login;
#check to see if the form was submited and that the values are equal.
{
if (strlen($_POST['hvalue']) > 1 && $_SERVER['REMOTE_ADDR'] == Zcrypt::Decrypt($_POST['hvalue']) )
{
Login::DoLogin(); ###### This is where I call my static Login Class
}
else {
echo "bad form";
}
}
Login.class.php
namespace net\[domain]\helpdesk;
use \net\[domain]\helpdesk\DB;
use \net\[domain]\Zcrypt;
class Login
{
public function DoLogin()
{
#call to the database class to open the db
$DB = new DB();
$DB->dbConnect();
#This is to show I can call Zcrypt in this class (note, no \) and it works.
echo $dbPass = Zcrypt::Decrypt("[coded string]");
}
}
DB.class.php
namespace net\[domain]\helpdesk;
use \net\[domain]\Zcrypt;
class DB
{
public $dbHost = '[address]';
public $dbUser = '[un]';
public $dbPass = '[pw]';
######The two commented out lines below will not run. I get a syntax error
# public $dbPass = \Zcrypt::Decrypt("[strint]");
# public $dbPass = Zcrypt::Decrypt("[string]")
public $dbName = '[name]';
public $db;
public function __construct(){}
public function dbConnect()
{
[code]
}
}
Cryptv2.class.php
namespace net\[domain];
use Exception;
class Zcrypt
{
public static function Encrypt($i)
{
[code]
}
public static function Decrypt($i)
{
[code]
}
}
Thanks for your help.
It's syntax error. You cannot use expressions in property definition.
This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated.
http://php.net/manual/en/language.oop5.properties.php
You would have to use \net\[domain]\Zcrypt:: for this to work. Or better yet assign an alias like use \net\[domain] as z, then z\Zcrypt::. In other words see the PHP manual http://php.net/manual/en/language.namespaces.php . Find file4. It has the example you need.
I'm very confused about using the parameters through pages with PHP OO.
I'm following a tutorial about creating a framework (it's just like the Zend Framework); but, what I don't understand is when this happens:
Example, the index:
// File: sourcefiles/index.php
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', realpath(dirname(__FILE__)).DS );
define ('APP_PATH',(ROOT.'aplicacion'));
require_once APP_PATH. DS.'Config.php';
require_once APP_PATH. DS.'Request.php';
require_once APP_PATH. DS.'BootStrap.php';
require_once APP_PATH. DS.'Controller.php';
require_once APP_PATH. DS.'View.php';
try
{
BootStrap::run(new Request());
I have:
// File: sourcefiles/controladores/IndexController.php
<?php
class IndexController extends Controller
{
public function __construct() {
parent::__construct();
}
public function indexAction()
{
$this->view->titulo='Homepage';
$this->view->contenido='Whatever';
$this->view->renderizar('index');
}
}
?>
And this:
// file : sourcefiles/aplicacion/View.php
<?php
class View
{
private $controlador;
private $layoutparams;
public function __construct(Request $peticion)
{
$this->controlador = $peticion->getControlador();
}
public function renderizar($vista,$item=false)
{
$rutaview = ROOT.'vistas'.DS.$this->controlador.DS.$vista.'.phtml';
if (is_readable($rutaview))
{
include_once $rutaview;
}
else
{
throw new Exception('Error de vista');
}
}
}
?>
And here is the View:
// file : sourcefiles/vistas/index/index.phtml
<h1>
Vista index..
<?php
echo $this->titulo;
echo $this->contenido;
?>
</h1>
Now my questions are:
How the IndexController can use the line? $this->view->titulo = blabla;
The view class doesn't have a "titulo" attribute; however, I can do that. But here is a curious thing, if I do that after calling the $this->view->renderizar('index'), I get the error.
How does the index.phtml file knows this? echo $this->titulo; because, there isn't a include or require called, it's confusing to me.
When I do a require or include call in a file, the required or included file knows the caller's variables?
If somebody can explain these to me, I would really appreciate it :D
or link me to a discussion on official information about this, or how is this called?
Think of an include or require line as "copy-and-pasting" the code from one file into another. This isn't quite accurate, but it explains part of the behaviour here:
In sourcefiles/aplicacion/View.php you include sourcefiles/vistas/index/index.phtml while inside the function View->renderizar. So all the code in index.phtml gets loaded as though it was happening inside that function too. This is why you can access $this, for instance.
As for referencing $this->view->titulo when you haven't defined it, this is PHP letting you be lazy. Just like any variable, a member on an object will spring into life as soon as you mention it, with only a notice warning that maybe you made a mistake.