I have a little issue with deleting a part of string using php.
Let me get you a little bit into problem, I have vlariable "column1text" in which is text string endered into < textarea >, but that does not matter. I want to remove all HTML tags from this string since they are doing problems sometimes. For example: When this string contains < /body > or < /table > it will do a lot of unwanted mess. So I want to get these tags away.
I am using $column1text = str_replace("TEXT TO REMOVE", "", $column1text); and it works, but I want to make function for it (optionaly if you know easier way, just tell me, I'll be glad).
I am using this function:
function remove($removetext)
{
$column1text = str_replace($removetext, "", $column1text);
}
And I am using it like this:
remove("TEXT TO REMOVE");
What am I doing wrong? (I am sure it's something pretty silly, but I cannot find it!)
P.S. I am totally sorry about my English, it must sound stupid, but I had no other idea than asking you.
You can either pass in $column1text as reference, or have your function returns the modified text (which I prefer)
function remove($column1text, $removetext) {
return str_replace($removetext, "", $column1text);
}
$column1text = remove($column1text, '<span>');
You are passing by value, when you actually need to be passing by reference. If you don't know what the difference is I suggest reading up a little on it.
Link
edit:
In a nutshell, whenever you pass a function a parameter, that function makes a copy of whatever it was passed, so when that parameter is manipulated in the function, it manipulates the copy and not the passed object itself.
When a function has a parameter passed by reference, then it actually has access to the object that was passed itself. That means anything you do to manipulate that object also affects the object outside of the function (since its not just a copy of it you are working with).
You need to tell interpreter that you want to use global variable, because now it sees it as local variable (within your function). To do this you just need to use global keyword:
function remove($removetext) {
global $column1text;
$column1text = str_replace($removetext, "", $column1text);
}
you can read more about it here http://php.net/manual/en/language.variables.scope.php
Related
I am having to do:
$sourceElement['description'] = htmlspecialchars_decode($sourceElement['description']);
I want to avoid that redundant mention of the variable name. I tried:
htmlspecialchars_decode(&$sourceElement['description']);
and
call_user_func('htmlspecialchars_decode', &$sourceElement['description']);
That did not work. Is this possible in PHP? Call a function on a variable?
You could create your own wrapper function that takes the variable by reference:
function html_dec(&$str) {$str = htmlspecialchars_decode($str);}
Then call:
html_dec($sourceElement['description']);
The correct solution would be to include that "redundant" variable mention. It's far more readable, and far less confusing that way.
$sourceElement['description'] = htmlspecialchars_decode($sourceElement['description']);
Your way of thinking is good though, you're thinking how to shorten your code, like a true lazy programmer =)
It depends on function. htmlspecialchars_decode() returns the result, it doesn't modify the original variable. And you can do nothing about it.
Most functions in PHP are immutable in mature, i.e. they don't modify the arguments you pass into them. This has a few advantages, one of them being able to use their return value in expressions without side effects.
Here's a generic wrapper you could use to mimic mutable behaviour for any function that takes a single argument:
function applyFn(&$s, $fn)
{
return $s = $fn($s);
}
applyFn($sourceElement['description'], 'htmlspecialchars_decode');
applyFn($sourceElement['description'], 'trim'); // trim string
Mileage may vary :)
Example:
function create_pets(&$cats, &$dogs){
$dogs = get_dogs();
$cats = get_cats();
}
so I would call it like:
function foo(){
create_pets($cats, $dogs);
// here use $cats and $dogs variables normally
}
I know that I could just assign a new varible the return value of one of those getter functions, but this is just an example. In my situation there's more than just a getter...
The answer as everyone says is "it depends". In your specific example, a "create" function, the code is less obvious to work with and maintain, and thus it's probably a good idea to avoid this pattern.
But here's the good news, there's a way of doing what you are trying to do that keeps things simple and compact while using no references:
function create_pets(){
return array(get_dogs(), get_cats());
}
function foo(){
list($dogs, $cats) = create_pets();
//here use $cats and $dogs variables normally
}
As you can see you can simply return an array and use the list language construct to get the individual variables in a single line. It's also easier to tell what's going on here, create_pets() is obviously returning new $cats and $dogs; the previous method using references didn't make this clear unless one inspected create_pets() directly.
You will not find a performance difference of using either method though, both will just work. But you'll find that writing code that is easy to follow and work on eventually goes a long way.
It depends on the circumstance. Most of the time you would usually call variables by value but in certain situations where you want to modify a variables content without changing the variable's value in other parts of the code, then calling by reference is a good idea. Other wise if you only want the actual content and only the actual content then calling by value is a better idea. This link explains it real well. http://www.exforsys.com/tutorials/c-language/call-by-value-and-call-by-reference.html
function do_sth_with_var($variable) {
if (is_by_reference($variable)) {
$variable = something($variable)
}
else {
return something($variable);
}
}
so for example if 'something' was strtoupper:
do_sth_with_var(&$str); // would make $str uppercase, but
$str = do_sth_with_var($str); // that way should it be done if ommitting that '&'
Disclaimer: This does not directly answer the OP's question, but I'm providing this answer in the hope that it will help him/her.
I'd say, provide a consistent interface. Declare the function parameter as reference:
function do_sth_with_var(&$variable) {
and it will always be a reference.
You could also to the contrary and always copy the value:
function do_sth_with_var($variable) {
$val = $variable;
// work with $val here
return $val;
}
No built-in PHP function I know changes its behaviour based on whether you pass a reference or not. They are clearly defined to either treat an argument as reference or not and I would argue that users are used to this clear definitions and can deal with them.
For example, sort always sorts an array in place. You know that. So if you want to keep the original, you make a copy before the call.
It depends on your function whether it makes sense to perform an in-place operation or not. E.g. it makes sense for sort but I'd say it does not make sense for string processing.
Also, as you are using PHP 5.3, passing variables by reference at call-time is deprecated:
As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.
So you (or whoever) should not do that anyway.
calltime-pass-by-ref is considered deprecated as of 5.3.
apart from that ... answering the question academically; I don't think there is any way to determine that propperly, b/c there is no difference between a "reference" and a usual parameter. In PHP every variable is a pointer to section in the symbol table. A reference just makes another variable point to the same section.
in PHP there are no references as C knows them for example. every variable is a pointer and every "reference" too.
PS: #Gordon: I forgot about the Reflection-Classes. Of course, they work on a meta-level. My answer is more directed at how PHP actually deals with paramters and variables.
This topic is covered very well by the first comment here (official php manual)
to answer your question literally, you can try experimenting with debug_zval_dump. Refcounts will be different for by val and by reference parameters.
function xxx($a) {
debug_zval_dump($a);
}
$b = 123;
xxx($b); // long(123) refcount(4)
xxx(&$b); // long(123) refcount(1)
In your specific case you don't need to know if the value is passed by reference or not you can do something like:
function do_sth_with_var($variable) {
$variable = something($variable)
return $variable;
}
It should do exactly what you ask in your question
I don't know any good and safe way to control that a passed parameter is a reference and not just a value inside the body of a function at running time.
I know that directly setting a variable in the scope of caller is probably not a good idea.
However, the PHP extract() function does exactly that! I would like to write my own version of extract() but cannot figure out how to actually go about setting the variables in the caller. Any ideas?
The closest I have come is modifying the caller's args using debug_backtrace(), but this is not exactly the same thing...
You can't modify local variables in a parent scope - the method which extract() uses is not exposed by PHP.
Also, what you get back from debug_stacktrace() isn't magically linked to the real stack. You can't modify it and hope your modifications are live!
You could only do it in a PHP extension. If you call an internal PHP function, it will not run in a new PHP scope (i.e., no new symbol table will be created). Therefore, you can modify the "parent scope" by changing the global EG(active_symbol_table).
Basically, the core of the function would do something like extract does, the core of which is:
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
//loop through the given array
ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table),
Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, data, 1, 0);
There are, however, a few nuances. See the implementation of extract, but keep in mind a function that did what you wanted wouldn't need to be as complex; most of the code in extract is there to deal with the several options it accepts.
You can abuse the $GLOBALS scope to read and write variables from the caller of your function. See below sample function, which reads and write variables from the caller scope.
And yes, I know its dirty to abuse the $GLOBAL scope, but hey, we're here to fix problems ain't we? :)
function set_first_name($firstname) {
/* check if $firstname is defined in caller */
if(array_key_exists('firstname', $GLOBALS)) {
$firstname_was = $GLOBALS['firstname'];
} else {
$firstname_was = 'undefined';
}
/* set $firstname in caller */
$GLOBALS['firstname'] = $firstname;
/* show onscreen confirmation for debugging */
echo '<br>firstname was ' . $firstname_was . ' and now is: ' . $firstname;
}
set_first_name('John');
set_first_name('Michael');
The function returns the following output:
<br>firstname was undefined and now is: John
<br>firstname was John and now is: Michael
It depends on how badly you need to do this. If it's only for source beauty, find another way. If, for some reason, you really need to mess with parent scope, there's always a way.
SOLUTION 1
The safest method would be to actually use extract itself for this job, since it knows the trick. Say you want to make a function that extracts elements of an array but with all the names backwards - pretty weird! -, let's do this with a simple array-to-array transformation:
function backwardNames($x) {
$out = [];
foreach($x as $key=>$val) {
$rev = strrev($key);
$out[$rev] = $val;
}
return $out;
}
extract(backwardNames($myArray));
No magic here.
SOLUTION 2
If you need more than what extract does, use eval and var_export. YES I KNOW I KNOW everybody calm down please. No, eval is not evil. Eval is a power tool and it can be dangerous if you use it without care - so use it with care. (There is no way to go wrong if you only eval something that's been generated by var_export - it doesn't give any way to intrusions even if you put values in your array from an untrusted source. Array elements behave well.)
function makeMyVariables() {
$vars = [
"a" => 4,
"b" => 5,
];
$out = var_export($vars,1);
$out = "extract(".$out.");";
return $out;
}
eval(makeMyVariables()); // this is how you call it
// now $a is 4, $b is 5
This is almost the same, except that you can do a lot more in eval. And it's significantly slower, of course.
However, indeed, there is no way to do it with a single call.
I'm trying to figure out how to know what has been done to a variable.
Here's an example:
function a($hello) {
$out .= strtoupper(ucwords(strtolower($hello)));
return $out;
}
echo function_trace('$hello') // returns array(strtoupper,ucwords,strtolower)
Thanks!
Matt
There's not really an easy way to do this, because variables don't store "state" or "history". Stack traces (where you probably got your inspiration from) are possible because they're generated from the existing execution stack, which is stored out of necessity to be able to properly unwind chains of function calls.
In addition, your example is trying to trace a function parameter - but that parameter variable is only defined within the scope of the function. Attempting to reference it outside of the function would result in the interpreter not knowing what variable you're trying to indicate - it'd think you're looking for a globally-scoped $hello, not the one used as an argument in the function.
There's no hook in PHP that does exactly what you want, but you can get a call stack with debug_backtrace():
http://php.net/manual/en/function.debug-backtrace.php
It's not possible to do exactly what you're asking for, but perhaps if you gave a bit more context about what you were hoping to do with that function trace, we could give some suggestions?