Reputation: 331
I'm trying to put all my PHP functions in a separate file. I'm using require
to include them in the controller file but I get errors with undefined variables in the view file.
For example:
A function stored in a file 'functions.php' validating my contact form (for the sake of clarity reduced here to validating only one field):
function validateContactForm()
{
if (empty($_POST['name'])) {
$name_error = 'Name is required.';
} else {
$name = ($_POST['name'];
if (!preg_match("/^[A-Za-z .'-]+$/", $name)) {
$name_error = 'Enter a valid name.';
}
}
}
In my controller I put this require 'functions.php';
.
My view file which gives undefined variable errors. It's just an HTML file with PHP code echoing validation messages.
<form
name="contact"
action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>"
method="post">
<label
for="name"
id="name-form">
Name:
</label>
<span id="name-error">
<?php echo $name_error; ?></span>
</form>
It all works great when I put the PHP code without enclosing it in a function on top of the view file. I've tried to return $name
in the function, I've tried require_once
and also I used $name
as an argument in the function: validateContactForm($name)
.
I have followed some simple tutorials where return
statement is supposed to be enough but obviously I'm missing something.
Looks like my view file can't access the variables in the function validateContactForm()
.
Upvotes: 0
Views: 74
Reputation: 4062
The variables in your functions.php
file have file-scope. You may access them with the use of global
or $GLOBALS
or the use
keyword on anonymous functions.
I recommend, that you use classes to store your functions.
Please note, that it is not good practice to use globals in the first place.
Anyway, you could use any one of these options below*:
*This list of options may not be complete.
./lib.php
<?php
// variables have file-scope, can`t be used directly via require
$foo = 1;
$bar = 2;
// anonymous functions can use the keyword `use` to access the variable
$callFoo = function() use ($foo) {
echo $foo;
};
// with normal functions, we use the global keyword to get the variable
function callBar() {
global $bar;
echo $bar;
}
// alternative to the one above ...
function callBarAlternative() {
echo $GLOBALS['bar'];
}
// working with classes:
class Foo {
public $publicFoo = 3;
private $privateFoo = 4;
function fooMethod() {
echo $this->privateFoo;
}
}
./view.php
<?php
require "lib.php";
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="text/html" charset="utf-8">
</head>
<body>
<?php
$callFoo();
callBar();
callBarAlternative();
$foo = new Foo();
echo $foo->publicFoo;
$foo->fooMethod();
echo $GLOBALS['bar'];
global $bar;
echo $bar;
?>
</body>
</html>
The output for these calls will be: 1223422
Upvotes: 2
Reputation: 123
The most right way for me to do this looks like this (based on the general code logic):
/**
* @param Array $POST
*/
function validateContactForm($POST){
if( empty($POST['name']) ){
throw new Exception('Name is required');
}
if (!preg_match("/^[A-Za-z .'-]+$/", $POST['name'])) {
throw new Exception('Enter a valid name');
}
}
Then in the view you can do:
try {
validateContactForm($_POST);
}
catch (Exception $e) {
// show the error to the user somehow..
}
By this way, you can expand the logic in the function however you wish later and not be able to change code elsewhere. You can also check & validate multiple $_POST data.
Upvotes: 0
Reputation: 102
The PHP variables inside a function have a local scope and so they are not visible outside. Use the "global" keyword to indicate that the variable is global.
function validateContactForm()
{
global $name_error, $name;
if (empty($_POST['name'])) {
$name_error = 'Name is required.';
} else {
$name = ($_POST['name'];
if (!preg_match("/^[A-Za-z .'-]+$/", $name)) {
$name_error = 'Enter a valid name.';
}
}
}
Upvotes: 1