I want some functions to be not visible when required, but visible in the script they belong to.
For example:
required.php:
<?php
function privateFunction() {
echo 'from private function\n';
}
echo 'from required.php: ';
privateFunction();
index.php:
<?php
require './required.php';
echo 'from index.php: ';
privateFunction(); // I want this to give an error like "private function called outside the script it has been declared".
I have already tried making the function private, but it only gives a parse error.
required.php:
<?php
class A {
private function privateFunction() {
echo 'from private function\n';
}
}
This is a probably a bad idea in general (see comments above), but the following should do what you're asking.
It makes use of debug_backtrace() to grab the file name of the function then the file name of the function's caller, and compares them. If they don't match, it throws an exception:
function assertCalledByCurrentScript(): void
{
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
if (isset($backtrace[1]) && $backtrace[0]['file'] !== $backtrace[1]['file']) {
throw new \BadFunctionCallException("Cannot call {$backtrace[1]['function']} from outside of its defining script.");
}
}
Then use it like this:
function privateFunction()
{
assertCalledByCurrentScript();
// rest of your "private" function here
}
Basically only option you have is to hide private stuff inside class:
//Your file
class MyClass
{
public static function myAction()
{
$internalStuff = self::internalStuff();
return 'Using this function you can get what is inside internalStuff: ' . $internalStuff;
}
private static function internalStuff()
{
return 'Some internal stuff not accessible from outside';
}
}
function myAction()
{
return MyClass::myAction();
}
//Otherfile
//require yourfile.php
//You can only use `myAction` as function
echo myAction();
//Or call
echo MyClass::myAction();
//But you cannot use `internalStuff
echo MyClass::internalStuff();
Related
By using the following class:
class SafeGuardInput{
public $form;
public function __construct($form)
{
$this->form=$form;
$trimmed=trim($form);
$specialchar=htmlspecialchars($trimmed);
$finaloutput=stripslashes($specialchar);
echo $finaloutput;
}
public function __destruct()
{
unset($finaloutput);
}
}
and Calling the function, by the following code, it works fine.
<?php
require('source/class.php');
$target="<script></script><br/>";
$forminput=new SafeGuardInput($target);
?>
But if in the SafeGuardInput class if I replace echo $finaloutput; with return $finaloutput; and then echo $forminput; on the index.php page. It DOES NOT WORK. Please provide a solution.
You can't return anything from a constructor. The new keyword always causes the newly created object to be assigned to the variable on the left side of the statement. So the variable you've used is already taken. Once you remember that, you quickly realise there is nowhere to put anything else that would be returned from the constructor!
A valid approach would be to write a function which will output the data when requested:
class SafeGuardInput{
public $form;
public function __construct($form)
{
$this->form=$form;
}
public function getFinalOutput()
{
$trimmed = trim($this->form);
$specialchar = htmlspecialchars($trimmed);
$finaloutput = stripslashes($specialchar);
return $finaloutput;
}
}
Then you can call it like in the normal way like this:
$obj = new SafeGuardInput($target);
echo $obj->getFinalOutput();
I just want to ask if its possible to call variables on class to another page of the site. I have tried calling the function's name and inside the parenthesis. I included the variable found inside that function e.g:
<?php
$loadconv -> loadmsg($msgReturn);
echo $loadconv;
?>
But it didn't work.
Do you want something like this?
class Load
{
public $msgReturn;
__construct()
{
}
public function loadMsg($param)
{
$this->msgReturn = $param;
}
}
Then you could do
$loadConv = new Load();
$loadConv->loadMsg('just a string');
echo $loadConv->msgReturn; // 'just a string'
Same function name in different isolated classes is not allowed?
What am I doing wrong?
I reduced my real code to the minimum required to make some test.
Here it is:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
class confFunctions {
function getConf() {
function doWork() {
echo "I am from confFunctions!<br />";
}
doWork();
}
}
class thePage {
function loadPage() {
function doWork() {
echo "I am from thePage!<br />";
}
doWork();
}
}
// Start check.
echo "Checking...<br />";
$conf = new confFunctions();
$conf->getConf();
$page = new thePage();
$page->loadPage();
?>
The output is:
Checking...
I am from confFunctions!
Fatal error: Cannot redeclare doWork() (previously declared in /var/www/Test2/index.php:11) in /var/www/Test2/index.php on line 23
Renaming one of the shared-name functions makes all working well. That is, changing doWork to doWork1 in the second class, like this:
class thePage {
function loadPage() {
function doWork1() {
echo "I am from thePage!<br />";
}
doWork1();
}
}
gives correct results:
Checking...
I am from confFunctions!
I am from thePage!
Should not what is inside a class be visible only to that class, if not declared public?
By declaring a function in a function, you are actually declaring the second function into the global scope.
If you want your functions to be limited to the class scope, don't declare a function in another function, but rather declare them under each other.
Consider this code that declares a function in another function (in a class):
<?php
class MyFunctions {
function load() {
function doWork() {
echo "I am doing my work from global scope";
}
}
}
$mf = new MyFunctions();
$mf->load();
// $mf->doWork(); <-- won't work here
doWork(); // <-- this will work!
?>
Now consider this code that declares a function under another function (in a class).
<?php
class MyFunctions {
function load() {
//...
}
function doWork() {
echo "I am doing my work from class scope";
}
}
$mf = new MyFunctions();
// $mf->load(); <-- not really important anymore
$mf->doWork(); // <-- this will work now
// doWork(); <-- won't work here anymore
?>
Function scope is always namespace wide when declaring a named function.
You'll need to assign it to a variable to constrain it to a specific scope ($doWork = function() { }).
You seem to be going down an odd path though. Perhaps you should just use a private method?
Full example just to make it clear:
class confFunctions {
function getConf() {
$doWork = function() {
echo "I am from confFunctions!<br />";
};
$doWork();
}
}
class thePage {
function loadPage() {
$doWork = function() {
echo "I am from thePage!<br />";
};
$doWork();
}
}
I dont think you meant to nest the functions ? and your calling them from the global scope.
something like this is likely what you meant
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
class confFunctions {
function getConf() {
$this->doWork();
}
function doWork() {
echo "I am from confFunctions!<br />";
}
}
class thePage {
function loadPage() {
$this->doWork();
}
function doWork() {
echo "I am from thePage!<br />";
}
}
// Start check.
echo "Checking...<br />";
$conf = new confFunctions();
$conf->getConf();
$page = new thePage();
$page->loadPage();
?>
First guess would be that somehow you aren't properly closing your class from the first example. Different classes are definitely allowed to have the same function names, so there's something else going on in your code here that's not being shown through the psuedo-code you're posting.
UPDATE:
As NL-X said, by posting the function inside of a class function it then creates it in global scope. Thank you for updating your pseudo-code with actual examples.
<?php
try{
$test = new TestAccessModifiers("2345","xyz","vfd","a0001","99","67"); /*invoking the class*/
var_dump($test->calculate());
}
catch(Exception $e){
echo $e->getMessage();
}
?>
<?php
class TestAccessModifiers {
function TestAccessModifiers($user_p,$user_fn,$user_ln,$user_id,$marks1,$marks2) {
echo "hello1";
$this->user_phone=$user_p;
$this->user_fname=$user_fn;
$this->user_lname=$user_ln;
$this->user_id=$user_id;
$this->marks1=$marks1;
$this->marks2=$marks2;
echo $this->marks1;
}
private $additional_marks = 10;
public static function calculate(){
return $this->marks1+$this->marks2+$this->getAdditionalmarks();
}
public function getAdditionalmarks(){
return $this->additional_marks;
}
}
?>
Above is the simple code i am trying to run... but i am unable to call TestAccessModifiers
I have tried using _constructor too
Rename your TestAccessModifiers function to __construct.
public function __construct($user_p,$user_fn,$user_ln,$user_id,$marks1,$marks2) {
echo "hello1";
$this->user_phone = $user_p;
$this->user_fname = $user_fn;
$this->user_lname = $user_ln;
$this->user_id = $user_id;
$this->marks1 = $marks1;
$this->marks2 = $marks2;
echo $this->marks1;
}
Then, remove static from calculate function.
It should then works..
Reference: http://php.net/manual/en/language.oop5.decon.php
if you are calling the class in another php page, make sure you include it like this.
include('/path/to/your/class.php');
$test = new TestAccessModifiers("2345", "xyz", "vfd", "a0001", "99", "67");
or if you are instantiating the object within the same file then place the instantiation code below your class.
class TestAccessModifiers {
public function __construct($user_p, $user_fn, $user_ln, $user_id, $marks1, $marks2) {
echo "hello1";
$this->user_phone = $user_p;
$this->user_fname = $user_fn;
$this->user_lname = $user_ln;
$this->user_id = $user_id;
$this->marks1 = $marks1;
$this->marks2 = $marks2;
echo $this->marks1;
}
private $additional_marks = 10;
public function calculate() {
return $this->marks1 + $this->marks2 + $this->getAdditionalmarks();
}
public function getAdditionalmarks() {
return $this->additional_marks;
}
}
try {
$test = new TestAccessModifiers("2345", "xyz", "vfd", "a0001", "99", "67"); /*invoking the class*/
var_dump($test->calculate());
} catch (Exception $e) {
echo $e->getMessage();
}
you have defined a static method in your class, and have used the pseudo variable $this inside of the static method, which PHP does not allow. since static method is treated out of object context in PHP. you need to remove the static method to use $this
First: Which PHP version you have?
Second: Are you including the class file in the file that you are instancing?
Third: Your function "calculate" is static, then, you can't access to it from an instance and it have no way to read or write properties non-statics.
Try TestAccessModifiers::calculate(); and put in a simple return "Hello World"
Greetings.
What version of PHP are we talking about?
First thing comes to mind: did you add it to autoload ?
I would use the __constructor methode as initiator routine of the class.
public static function calculate() {
return $this - > marks1 + $this - > marks2 + $this - > getAdditionalmarks();
}
You can't operate on $this from a static context. Make this method non-static, or adjust the other variables to be static, whichever suits your context.
Example code:
class MyClass {
function echo_msg {
echo // now what...
}
function echo_from_inside {
$this->echo_msg()
}
}
result should be:
$my_instance = new MyClass();
$my_instance->echo_msg(); // I was called from OUTside
$my_instance->echo_from_inside(); // I was called from INside
It might be easier, rather than detecting from whence the function was called, to wrap a private function with a public one. Like so:
class MyClass{
private function myob(){
//do something
}
public function echo_msg(){
$this->myob();
//do other stuff like set a flag since it was a public call
}
private function foo(){ //some other internal function
//do stuff and call myob
$this->myob();
}
}
$obj=new MyClass();
$obj->echo_msg();//get output
$obj->myob(); //throws error because method is private
You can try and get the caller of your method:
$trace = debug_backtrace();
$caller = array_shift($trace);
echo 'called by '.$caller['function']
echo 'called by '.$caller['class']
this should work for you.
You could add an optional parameter like such:
function echo_msg($ins=false) {
if($ins){/*called from inside*/}else{/*called from outside*/}
echo // now what...
}
and leave that last. If you are calling it from inside the class, pass it true, otherwise pass nothing!