So I thought this should be easy, but, I'm struggling here...
Here's my code:
function xy() {
$array['var1'] = x;
$array['var2'] = y;
echo $this->_z;
}
function _z($array) {
$xy = $x.$y;
return $xy;
}
So, why doesn't that seemingly simple code work? I know with views you can pass arrays and the variables are accessible in the views with just their array title, but, why doesn't it work in this case?
Because function _z is not a view. Call it with $this->_z($array);. Also views are processed by CodeIgniter and variables passed into them. This doesn't work the same way for non-views. PHP won't do that automatically for you.
To load a view make a view file in /system/application/views/ and call it with $this->load->view('my_view_name', $array);
I would rewrite your functions as follows:
function xy()
{
$x = "some value";
$y = "some other value";
echo $this->_z($x, $y);
}
function _z($a, $b)
{
return $a.$b;
}
You can mimic the CI views behavior you want with the PHP native function extract() (That is how CI does it)
function xy() {
$some_array = array(
'foo' => 'Hello',
'bar' => 'world'
);
echo $this->_z($some_array);
}
function _z($array) {
extract ($array);
$xy = "$foo $bar";
return $xy;
}
xy();
Reference: http://php.net/manual/en/function.extract.php
One of the best explanation about accessing array from a function to a private function. thanks the code helped me
function _normal()
{
$arrayVariable = "value you want to pass";
echo $this->_toPrivateFuction($arrayVariable);
}
function _toPrivateFuction($arrayVariable)
{
// or print to check if you have the desired result
print_r(arrayVariable);
// if yes then you are ready to go!
return $arrayVariable;
}
Related
I'm trying to achieve almost similar things/properties of closure in PHP which is available in JS.
For example
function createGreeter($who) {
return function(){
function hello() use ($who) {
echo "Hi $who";
}
function bye() use($who){
echo "Bye $who";
}
};
}
I know my syntax is incorrect, this what I'm trying to achieve.
What I've done so far is.
function createGreeter() {
$hi = "hi how are you.";
$bye = "bye wish you luck.";
return function($operation) use ($hi, $bye){
if ($operation == "a") return $hi;
elseif ($operation == "b") return $bye;
};
}
$op = createGreeter();
echo $op("a"); #prints hi how are you.
echo $op("b"); #prints bye wish you luck.
Please look does PHP allows us to do this.
You could return an anonymous class which is created with the $who and then has methods which output the relevant message...
function createGreeter($who) {
return new class($who){
private $who;
public function __construct( $who ) {
$this->who = $who;
}
function hello() {
echo "Hi {$this->who}";
}
function bye(){
echo "Bye {$this->who}";
}
};
}
$op = createGreeter("me");
echo $op->hello(); // Hi me
echo $op->bye(); // Bye me
Decided to post as a new answer as it's a completely different solution. This follow the idea of creating private methods using closures (as linked to by OP in comment to my other answer - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Emulating_private_methods_with_closures).
This also draws on deceeze's comments on the original question, but casting the array to an object to more closely reflect the reference as being an object rather than an array...
function createGreeter($who) {
return (object)
[ "Hello" => function() use ($who) {
echo "Hello {$who}";
},
"Goodbye" => function() use ($who) {
echo "Goodbye {$who}";
}];
}
$op = createGreeter("me");
($op->Hello)();
($op->Goodbye)();
The ()'s around the methods are needed as it is a closure and not an actual method.
This gives...
Hello meGoodbye me
I am writing some PHP code that would generate HTML files from templates.
I would like, if possible, to make a function that would take any strings I feed the function with, and put that into the file. Like so:
function generator($a, $b, $c, $n...){
$filename = $a . ".html";
ob_start ();
echo $b;
echo $c;
echo $d;
echo $n...;
$buffer = ob_get_clean();
file_put_contents($a, $buffer);
}
I need this, because different pages would have different number of include files, and with this I would be able to skip making different functions for specific pages. Just an iterator, and that's it.
Thanks!
From PHP 5.6+ you can use ... to indicate a variable number of arguments:
function test (... $args)
{
foreach ($args as $arg) {
echo $arg;
}
}
test("testing", "variable"); // testing variable
Demo
Variable-length argument lists from the manual
So, your function would look something like this:
function generator($a, $b, $c, ... $n) {
$filename = $a . ".html";
ob_start();
echo $b;
echo $c;
foreach ($n as $var) {
echo $var;
}
$buffer = ob_get_clean();
file_put_contents($a, $buffer);
}
You can also use variadic functions (PHP 5.6+) :
function generator($a, ...$args) {
echo $a . "\n";
print_r($args);
}
generator("test", 1, 2, 3, 4);
Outputs :
"test"
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
You can make it using an array as following :
function generator($array){
// set the first item of the array as name of the .html file and take it out of the array.
$filename = array_shift($array) . ".html";
ob_start ();
// echo all the array fields
foreach($array as $a){
echo $a;
}
$buffer = ob_get_clean();
file_put_contents($a, $buffer);
}
You can pass the array directly to call the function like the following :
generator( ["val_1", "val_2", "val_3"] );
Just use func_get_args(); inside your function to return an array of all arguments passed in.
You can also use func_get_arg($arg_num) to return a specific argument, or func_num_args to return the number of arguments.
All PHP functions allow any number of parameters, they just won't be callable by name, the only way is with these 3 functions.
Note, you may use a variadic argument as the last in the parameter list like so:
function my_func($x,$y, ... $z){
//Now $z is an array of all arguments after the first two
}
In the process of good design, I would think carefully about when and where to use things such as this. For example I currently work on a project that probably has over 200K lines of code and for better of worse this is actually never used.
The most common way is to pass an array "struct" to the method:
$args = array();
$args['kitchen'] = 'sink';
$args['bath'] = 'room';
$args['cat'] = array('fur','tail');
$func->someFunction($args);
If you wanted to have more control over the data you could create a struct and access that within the class. Public functions act as handlers.
class SomeClass {
....
private $args
public function setArgs($arg1,$arg2,$arg3) {
$this->arg1 = $arg1;
...
}
public function getArgs() {
return $this->args;
}
More rarely you can have C++ like control where you use a class just as a struct:
class MyStruct {
public $foo;
public $bar;
private $secret;
private function getSecret() {
return $secret;
}
protect function setSecret($val) {
$secret = $val;
}
}
Already mentioned is '...' which I nearly never see but it's interesting, though how useful ? Does this help explain what is going on?
function someFunction(... $args)
Usually you will see a mix of things in methods which helps articulate the purpose of it.
private function someSmallFunc($list = array(), $val = '', $limit = 10)
This example is to illustrate the natural grouping of information, data is in a list, $val is used for something to control the method along with $limit say limits the number of query results. Hence, you should think in this way about your methods IMO.
Also if you notice default values are set ($limit = 10) to in case they aren't passed in. For example if you call someSmallFunc($data, $someVal) (opposed to say someSmallFunc($data, $someVal, 20) ) and not pass in $limit it will default to 10.
Say I got some function that run some code and then return something, like this:
function something()
{
//some code
return $some[$whatever];
}
So, if I want to extract the data I generated in the function - the new value for $some, how should I do it? for example this won't do anything:
echo ($some);
Or what am I missing here, please
Since your Function returns a value, You may need to catch & store it inside a variable and then echo the variable if it is a String or do some casting to that effect. Here's an example:
<?php
function something(){
//some code
$whatever = 3;
$some = ["Peace", "Amongst", "All", "Humanity"];
return $some[$whatever];
}
$var = something();
var_dump($var); //<== DUMPS :: "Humanity"
echo $var; //<== ECHOES:: "Humanity"
Test it out here.
Cheers and Good Luck....
You are trying to return a specif key from your array, which wasn't declared. I declared an array for you, and I added the isset to check if the key is existing in the array to prevent any php warnings.
function something($findKey)
{
$some = array('key'=> 123);
if(!isset($some[$findKey])) {
return false;
}
//some code
return $some[$findKey];
}
echo something('key');
What does the & before the function name signify?
Does that mean that the $result is returned by reference rather than by value?
If yes then is it correct? As I remember you cannot return a reference to a local variable as it vanishes once the function exits.
function &query($sql) {
// ...
$result = mysql_query($sql);
return $result;
}
Also where does such a syntax get used in practice ?
Does that mean that the $result is returned by reference rather than by value?
Yes.
Also where does such a syntax get used in practice ?
This is more prevalent in PHP 4 scripts where objects were passed around by value by default.
To answer the second part of your question, here a place there I had to use it: Magic getters!
class FooBar {
private $properties = array();
public function &__get($name) {
return $this->properties[$name];
}
public function __set($name, $value) {
$this->properties[$name] = $value;
}
}
If I hadn't used & there, this wouldn't be possible:
$foobar = new FooBar;
$foobar->subArray = array();
$foobar->subArray['FooBar'] = 'Hallo World!';
Instead PHP would thrown an error saying something like 'cannot indirectly modify overloaded property'.
Okay, this is probably only a hack to get round some maldesign in PHP, but it's still useful.
But honestly, I can't think right now of another example. But I bet there are some rare use cases...
Does that mean that the $result is returned by reference rather than by value?
No. The difference is that it can be returned by reference. For instance:
<?php
function &a(&$c) {
return $c;
}
$c = 1;
$d = a($c);
$d++;
echo $c; //echoes 1, not 2!
To return by reference you'd have to do:
<?php
function &a(&$c) {
return $c;
}
$c = 1;
$d = &a($c);
$d++;
echo $c; //echoes 2
Also where does such a syntax get used in practice ?
In practice, you use whenever you want the caller of your function to manipulate data that is owned by the callee without telling him. This is rarely used because it's a violation of encapsulation – you could set the returned reference to any value you want; the callee won't be able to validate it.
nikic gives a great example of when this is used in practice.
<?php
// You may have wondered how a PHP function defined as below behaves:
function &config_byref()
{
static $var = "hello";
return $var;
}
// the value we get is "hello"
$byref_initial = config_byref();
// let's change the value
$byref_initial = "world";
// Let's get the value again and see
echo "Byref, new value: " . config_byref() . "\n"; // We still get "hello"
// However, let’s make a small change:
// We’ve added an ampersand to the function call as well. In this case, the function returns "world", which is the new value.
// the value we get is "hello"
$byref_initial = &config_byref();
// let's change the value
$byref_initial = "world";
// Let's get the value again and see
echo "Byref, new value: " . config_byref() . "\n"; // We now get "world"
// If you define the function without the ampersand, like follows:
// function config_byref()
// {
// static $var = "hello";
// return $var;
// }
// Then both the test cases that we had previously would return "hello", regardless of whether you put ampersand in the function call or not.
In my includes folder I have a function...
function storelistingUno() {
$itemnum=mysql_real_escape_string($_POST['itemnum']);
$msrp=mysql_real_escape_string($_POST['msrp']);
$edprice=mysql_real_escape_string($_POST['edprice']); //This value has to be the same as in the HTML form file
$itemtype=mysql_real_escape_string($_POST['itemtype']);
$box=mysql_real_escape_string($_POST['box']);
$box2=mysql_real_escape_string($_POST['box2']);
$box25=mysql_real_escape_string($_POST['box25']);
$box3=mysql_real_escape_string($_POST['box3']);
$box4=mysql_real_escape_string($_POST['box4']);
$box5=mysql_real_escape_string($_POST['box5']);
$box6=mysql_real_escape_string($_POST['box6']);
$box7=mysql_real_escape_string($_POST['box7']);
$box8=mysql_real_escape_string($_POST['box8']);
$itemcolor=mysql_real_escape_string($_POST['itemcolor']);
$link=mysql_real_escape_string($_POST['link']);
$test = "yes!";
}
I reference this in about 8 pages and I decided it would be easier to just make a function out of it and only touch this from now on. So I referenced storelistingUno(); in my code, but I don't think it worked, because I tried to execute echo $test; and nothing happened. Do I need to return something?
Thanks.
Look into extract(). You can do something like this:
<?php
function getEscapedArray()
{
$keys = array('itemnum', 'msrp', 'edprice', 'itemtype', 'box', 'box2', 'box25', 'box3', 'box4', 'box5', 'box6', 'box7', 'box8', 'itemcolor', 'link');
$returnValues = array();
foreach ($keys as $key) {
$returnValues[$key] = mysql_real_escape_string($_POST[$key]);
}
$returnValues['test'] = 'yes!';
return $returnValues;
}
extract(getEscapedArray());
echo $test;
Although - Its still not the best way to do this. The best would be to just use the return from that function as the array.
$parsedVals = getEscapedArray();
echo $parsedVals["test"];
If you absolutely need these variables a globals
function storelistingUno()
{
$desiredGlobals = array(
'itemnum'
,'msrp'
,'edprice'
,'itemtype'
,'box'
,'box2'
,'box25'
,'box3'
,'box4'
,'box5'
,'box6'
,'box7'
,'box8'
,'itemcolor'
,'link'
);
foreach ( $desiredGlobals as $globalName )
{
if ( isset( $_POST[$globalName] ) )
{
$GLOBALS[$globalName] = mysql_real_escape_string( $_POST[$globalName] );
}
}
}
$test is a local variable in that function - you either need to make it global (by putting global $test; at the start of the function or using $GLOBALS['test'] instead of just $test or return the value.
Are you thinking of using that function to just escape the values? Maybe you could make it perform the query too, then you wouldn't have to return / use globals.
Edit:
A different way would be to include the code instead of using a function - not recommended though...
You would have to mark every variable as global before you start to edit them within the function ... this isn't recommented since it's bad coding style but it might help you
$test = '';
function foo() {
global $test;
$test = 'bar';
}
echo $test; //prints nothing
foo();
echo $test; // prints "bar"