This is my php function it must return "5" but it returns nothing.
<?php
function get_second($num){
$second = $num[1]; //must return second number of the variable.
return $second;
}
$numbers=456789;
echo get_second($numbers);
?>
When I tried out this code, this returns nothing (NULL, empty).
But I tried out this function below, worked perfectly.
<?php
function get_second($num){
$second = $num[1]; //must return second number of the variable.
return $second;
}
$numbers=$_POST['number_input'];//that includes numbers
echo get_second($numbers);
?>
This code returns me second number of the post data. What I must do to work my First function? What is the difference between first $numbers variable and second $numbers variable?
Here the problem has to be better defined: how to get the second digit from a number. Your initial approach was correct in logic, but incorrect in the assumption that a number is a order set of characters. Only strings are ordered set of characters. Once you transform the integer 45678 to the string 45678 you can easily intercept the second character by using substr or even directly the string - because in PHP strings can be treated as arrays of characters.
#RamRaider solution is better than other have suggested but is overkill to use preg_split. Other solutions ask you to modify the type of the variable which is not done by adding quotes, but is done by casting to string, which is simpler and faster than a regular expression and you maintain your original variable in original form and your original function definition.
function get_second($num){
$second = $num[1]; //must return second number of the variable.
return $second;
}
$numbers = 456789;
// casting to string
echo get_second((string)$numbers);
// or transform to string by concatenation to a string
echo get_second($numbers ."");
// even quoting works
echo get_second("$numbers");
// using strval
echo get_second(strval($numbers));
// using settype
echo get_second(settype($numbers, "string"));
Try this: (add quotes to your integer variable)
<?php
function get_second($num){
$second = $num[1]; //must return second number of the variable.
return $second;
}
$numbers="456789";
echo get_second($numbers);
?>
If you want to get Character by its number then you can use substr()
function get_second($num)
{
return substr($num,1,1);
}
$numbers="456789";
echo get_second($numbers);
you are declaring a number in the $number variable.
if you want to view the second element than you have to use string.
try
$numbers= "456789";
it will output 5.
You could use preg_split to force an array from which you can choose any number by index, like:
$number=12358397;
function get_number($num,$i){
$num=preg_split( '#^\d$#', $num );
return $num[0][$i];
}
echo ' [1] > > > ' . get_number($number,1);
Related
Is there a simple way to update the values of variables that are already present in strings (without using eval or replace functions) with the {$var} syntax?
In this example:
$id_a=1; $id_b = 2;
echo $str = "The id {$id_a} is related to id {$id_b}\n";
// operations go in here that calculate new values for $id_ variables
$id_a=124214; $id_b=325325;
echo $str = "The id {$id_a} is related to id {$id_b}\n";
You notice that I am assigning the same string twice to $str.
My goal is to assign only once and every time I echo $str if $id_a or $id_b were changed, $str would have the updated values.
If there is a function that achieves this (even if it was not intended for specifically doing this), I haven't found it yet and I would be glad to know about it...
Use sprintf to specify where the arguments need to appear in the string and pass $id_a and $id_b as parameters. E.g.
$id_a=1; $id_b = 2;
$format = "The id %d is related to id %d\n";
echo sprintf($format, $id_a, $id_b);
// operations go in here that calculate new values for $id_ variables
$id_a=124214; $id_b=325325;
echo sprintf($format, $id_a, $id_b);
This way you only declare your string's structure once and can re-use where-ever you need to output it. This also has the advantage of being able to convert your arguments into various formats (check the PHP docs page)
with the idea of Barmar, it makes that :
function calculateString($id_a, $id_b) {
return "The id {$id_a} is related to id {$id_b}\n";
}
$id_a=1; $id_b = 2;
echo $str = calculateString($id_a, $id_b);
$id_a=124214; $id_b=325325;
echo $str = calculateString($id_a, $id_b);
I've a variable titled $value as follows :
$value = 5985;
If I echo 05985; it prints 15. I understood that PHP considers this number as octal and prints 15 but I don't want 15 I want leading zero/zeroes prefixed to a value contained in a variable $value.
But I want to make it five or say six digits long. In that case I need to add leading zero/zeroes to the value contained in a variable $value. When I add those leading zeroes and echo the variable $value it should look like as follows :
05985; //If I want five digit number
005985; //If I want six digit number
I searched and tried following approach but it didn't work out.
str_pad($value, 8, '0', STR_PAD_LEFT);
sprintf('%08d', $value);
echo $value;
So can someone please suggest me how to do that?
Thanks.
Sprintf does not directly change the value of its second parameter, it returns the result. Try
$value = sprintf('%08d', $value);
You need to treat it as a string.
$number = '05433';
Echo $number;
Should give you what you want. You can also add a zero like this
$number = '0' . $number;
I'm confused as to how PHP determines whether a variable is a string or an array. It seems to depend on the operators being used.
Here's an example:
<?php
$z1 = "abc";
$out = "";
for ($i = 0; $i < strlen($z1); $i++)
{
// $out[$i] = $z1[$i];
$out = $out.$z1[$i];
}
print $out;
?>
In the above version $out becomes a string (print $z1 shows "abc"). However, if I use the first line $out[$i] = $z1[$i];, $out becomes an array.
Can someone please clarify why this happens, and if its possible to access a string's characters with square brackets without converting the output to an array?
The definition of a string in PHP is considered a set of data writen in linear format (i.e: $var = "username=SmokeyBear05,B-day=01/01/1980";)
An array however is a set of data broken down into several parts. A sort of list format if you will. As an example I've written the data string from before, into an array format...
Array(['username']=>"SmokeyBear05", ['B-day']=>"01/01/1980")
Now strings are generally defined as such: $var="Your String";
Arrays however can be written in three different formats:
$var1 = array('data1','data2','data3');
$var2 = array('part A'=>'data1','part B'=>'data2','part C'=>'data3');
The output of var1 starts the index value at 0. The output of var2 however, sets a custom index value. Now the third way to write an array (least common format) is as such:
$var[0]="data1";
$var[1]="data2";
$var[2]="data3";
This takes more work, but allows you to set the index.
Most web developers working with PHP will set data from an external source as a string to deliver it to another PHP script, and then break it down into an array using the explode() function.
When you define variable $out = "", for loop doesn't understand this variable as string value. If you set $out[$i] value, by default, it was treated as an array.
If you want to get the output result as string value, you can define $out = "a" to make sure it's a string variable.
I'm looking for the php equivalent of pythons % operator.
# PYTHON Example
foo = 'variable_string'
baz = 'characters'
new_string = 'my %(foo)s of %(baz)s' % locals()
My Vague php context:
Note: This is to demonstrate why I want to do this, it does not reflect any code.
// PHP Example context
class Controller {
...
// Singles quotes used in intentionally
// This template string is meant to be overloadable.
public $template = '<h1>{$title}</h1><h2>{$subheading}</h2>';
....
}
class View {
...
public function render($template) {
$title = 'variable string';
$subheading = 'some other variable stuff';
// Example of the python operator
return magically_put_variables_in_string(
$template,
magically_get_named_variables_from_scope()
);
}
...
}
Specifically I want the most canonical magically_put_variables_in_string implementation.
I cannot assume I will be able to use anything from later than php 5.3
I do not mind passing an explicit array('$variable_name' => $variable_name)
Points for doing it without defining a new function.
Final Note: I have built a work around for my specific use case, however it does not satisfy the question.
A good approach would be strtr:
strtr('<h1>{foo}</h1><h2>{bar}</h2>', array(
'{foo}' => $foo,
'{bar}' => $bar,
));
You can also use get_defined_vars() to get an array of variables accessible in the current scope, though I personally prefer explicit enumeration.
One of the subtle advantages of using strtr over str_replace is that strtr will not search the already-substituted portions of the string for further replacements. The manual page for str_replace states:
Because str_replace() replaces left to right, it might replace a previously inserted value when doing multiple replacements.
It sounds like you are trying to do typecast swapping. You can do this with two functions print_f and sprint_f. The first will echo the output, the second will return a string. You can pass named variables into the functions like so:
// PHP Example context
class Controller {
...
// Singles quotes used in intentionally
// This template string is meant to be overloadable.
public $template = '<h1>%s</h1><h2>%s</h2>'; // Update this line
....
}
class View {
...
public function render($template) {
$title = 'variable string';
$subheading = 'some other variable stuff';
return sprint_f($template, $title, $subheading);
}
...
}
UPDATE:
You can also target variables in typecast swapping by adding numerical specifiers to the types. Say you want the title twice for some reason:
public $template = '<h1>%1$s</h1><h2>%2$s</h2><h3>%1$s</h3>';
That will typecast swap the first variable (second argument) in the sprint_f() function in both the <h1> and the <h3>. The number you put in the specifier should match the argument location, so the %1$s will be the first argument following the $template and so on. You can have any number of typecast specifiers of any type. They are as follows:
% - a literal percent character. No argument is required.
b - the argument is treated as an integer, and presented as a binary number.
c - the argument is treated as an integer, and presented as the character with that ASCII value.
d - the argument is treated as an integer, and presented as a (signed) decimal number.
e - the argument is treated as scientific notation (e.g. 1.2e+2). The precision specifier stands for the number of digits after the decimal point since PHP 5.2.1. In earlier versions, it was taken as number of significant digits (one less).
E - like %e but uses uppercase letter (e.g. 1.2E+2).
f - the argument is treated as a float, and presented as a floating-point number (locale aware).
F - the argument is treated as a float, and presented as a floating-point number (non-locale aware). Available since PHP 4.3.10 and PHP 5.0.3.
g - shorter of %e and %f.
G - shorter of %E and %f.
o - the argument is treated as an integer, and presented as an octal number.
s - the argument is treated as and presented as a string.
u - the argument is treated as an integer, and presented as an unsigned decimal number.
x - the argument is treated as an integer and presented as a hexadecimal number (with lowercase letters).
X - the argument is treated as an integer and presented as a hexadecimal number (with uppercase letters).
I hope str_replace is what you are looking for.
Description ΒΆ
mixed str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
This function returns a string or an array with all occurrences of search in subject replaced with the given replace value.
You can give tokens array as subject and corresponding token values as array in replace.
<?php
# PHP Example
$foo = 'variable_string'
$baz = 'characters'
$new_string = str_replace(array("%foo%","%baz%"),array($foo,$baz), "my %foo% of %baz%s");
?>
<?php
// Provides: <body text='black'>
$bodytag = str_replace("%body%", "black", "<body text='%body%'>");
?>
You can use sprintf.
$template = '<h1>%s</h1>';
echo sprintf($template, 'Hello world');
Best way I can think of:
public function render($template) {
$data = array(
'{$title}' => 'variable string',
'{$subheading}' => 'other variable string'
);
return str_replace(array_keys($data), array_values($data), $template);
}
What I always loved about PHP was that it is preserving the underlying logic of strings as arrays of characters. In php you canb do just as you would in C ...
The code hereunder will replace all escaped names with whatever is defined in the replacements array (or with nothing if nothing is defined).
$replacements['color1'] = 'red';
$replacements['color2'] = 'green';
$template = "Apples are {color1} , grapes are {color2}\n";
// this will oputput 'Apples are red , grapes are green' and a newline
echo templatereplace($template,$replacements);
function templatereplace($template,$replacements)
{
// our output
$outputstring = "";
// run through the template character by character
for($n=0 ; $n<strlen($template) ; $n++)
{
// if the escaped string starts
if($template[$n] == '{')
{
// reset the name of the replacement variable
$replacementvar = '';
// set the flag
$escaped = 1;
// next round
continue;
}
// if the escaped string part stops
if($template[$n] == '}')
{
//echo "end\n";
// write the replacementvariable to outputstring
$outputstring .= $replacements[$replacementvar];
// set the flag
$escaped = 0;
// next round
continue;
}
// if we are in escapes state
if($escaped == 1)
// write current char to the replacementvar
$replacementvar .= $template[$n];
else
// write the current char to output string
$outputstring .= $template[$n];
}
// return the output string
return $outputstring;
}
Note: Differently from the str_replace and strtr solutions here above, this will also replace escaped variables that are present in the template but not defined in the replacement scope.
So basically, you want to do the following, but delaying the "parsing" of the string until you can define your variables in your own function?
$foo = 'variable_string';
$baz = 'characters';
$new_string = "my {$foo}s of {$baz}s";
echo $new_string; // 'my variable_strings of characterss'
As DCoder suggested in one of his answers, you can use the get_defined_vars(); function and go from there. Here's a solution using that method.
<?php
$template = '<h1>{$title}</h1><h2>{$subheading}</h2>';
function render($str) {
$title = 'Delayed String Parsing';
$subheading = 'As demonstrated by the following sample code';
$defined_variables = get_defined_vars();
$defined_variable_keys = array_keys($defined_variables);
$parsed_string = $str;
for ($i = 0; $i < count($defined_variable_keys); $i++) {
$var_name = $defined_variable_keys[$i];
$parsed_string = str_replace('{$' . $var_name . '}', $defined_variables[$var_name], $parsed_string);
}
return $parsed_string;
}
echo render($template);
You can see it running here: http://ideone.com/1WMQSr
simply
function map($string, $variables) {
$mapper = array();
foreach ($variables as $name => $value)
$mapper["#{$name}#"] = $value;
return strtr($string, $mapper);
}
function render($template) {
$foo = 'variable_string';
$baz = 'characters';
return map($template, get_defined_vars());
}
echo render('#foo# 123 #baz#aaa');
Maybe not a direct answer to your question, but it looks like you are trying to build your own MVC engine. If thats the case I find it strange that you define the template (view) in the controller and then define the logic (controller) in the view. I think it should be the other way around.
If you use it like that you can define all variables in the controller and simply use an include file as "view" and that would simplify things a lot and give you a lot more control.
<?php
class Model
{
private $_title;
private $_subHeading;
final public function __construct($title, $subHeading)
{
$this->_title = $title;
$this->_subheading = $subHeading;
}
final public function Title() { return $this->_title; }
final public function SubHeading() { return $this->_subHeading; }
}
class Controller
{
final public function __construct()
{
$model = new Model("variable string","some other variable stuff");
//in this example return isn't realy needed, but you could alter the view class to buffer the output and return it to the controller instead of just sending the output to the user directly.
return View::Render("test.php", $model);
}
}
class View
{
final static public function Render($viewTemplate, $model)
{
//Omitted: do some checking here for file exits etc.
//I include a masterpage first. This contains the main layout of the site and CSS/scripts etc.
//You could expand on this to have multiple different masterpages, but for this example I kept it simple with just one.
//you could use some output buffering around the include to be able to return the content to the controller.
include("masterpage.php");
}
}
?>
masterpage.php
<html>
<head>
<title><?php echo $model->Title(); ?></title>
</head>
<body>
<?php include($viewTemplate); ?>
</body>
</html>
test.php
<h1><?php echo $model->Title(); ?></h1><h2><?php echo $model->SubHeading(); ?></h2>
How you invoke the controller is up to you. Personally I would use .htaccess to send all request to a single php file and then start the right controller based on the URL. For simple testing you could just use $c = new Controller();
Final output to user:
<html>
<head>
<title>variable string</title>
</head>
<body>
<h1>variable string</h1><h2>some other variable stuff</h2>
</body>
</html>
If you trust the template enough you might give eval() a chance:
class View
{
public function render(array $model, $template)
{
extract($model);
return eval(sprintf('return "%s";', addslashes($template)));
}
}
$template = 'Hello "${object}"';
$model = array("object" => "world");
$view = new View();
$rendered = $view->render($model, $template);
echo $rendered, "\n";
A Code Golf style answer would be to just force re-parsing of the string with an eval:
$template = '<h1>{$title}</h1><h2>{$subheading}</h2>';
$title = 'variable string';
$subheading = 'some other variable stuff';
echo eval("return \"$template\";");
Don't do this in production, of course. :-)
so suppose I have a function:
function j($a, $b){
return $a + $b;
}
and then I put the intended arguments of the function into a string:
$str = '1,3';
is there a way to make the function treat the single string argument as if it were the arguments that the programmer inserted into the function....so when you do
j($str),
instead of having the function treat the $str as a single string argument, it fetches the content of the string and treats it as if the programmer wrote j(1,3) instead of j($str)
also this is a rather simple example, but I'd like it to work for even more complicated argument strings involving arrays, multidimensional arrays, associative arrays, array within arrays, as well as string arguments that have commas in it (so just exploding by comma is not really feasible)
also I'd rather not use eval() in the solution
EDIT
Also I'm trying to get this to work on any function not just mine (and not just this specific function which is just a worthless example function) so preferably the operation is to be done outside of the function
call_user_func_array('j', explode(',', $str));
http://www.php.net/call_user_func_array
I have no idea how you want to make this work for "more complex argument strings including arrays of arrays", since it's hard to express those as strings. If you can format whatever string you have into an array though, for example using JSON strings and json_decode, call_user_func_array is your friend.
This should work for a single, comma-separated string:
function j($str){
list($a, $b) = explode(',', $str);
return $a + $b;
}
What do you want to sum in a multi-dimensional array? All of the values?
If yes: You only have to check the type of your argument (e.g. using is_array()) and then iterate through it. When it is multi-dimensional, call your function recursively.
make all parameter but except the first one optional and then use list() and explode() if the first parameter is a string (or contains ,):
function j($a, $b=null){
if(strpos($a,',')!==false){
list($a,$b) = explode(',',$a)
}
return $a + $b;
}
this is just a basic example, but the principle should be clear:
check if one of the arguments is composed of multiple parameters
if so, parse it on your own to get the single parameters
function j($a, $b = 0){ // make second arg optional
if (! $b) { // is second arg specified and not zero
if (strpos($a, ',') !== false){ // has provided first arg a comma
list($first, $second) = explode(',' $a); // yes then get two values from it
return $first + $second; // return the result
}
}
else {
return $a + $b; // two args were passed, return the result
}
}
Now your function will support both formats, with one argument eg:
$str = '1,3'
j($str);
as well as two arguments:
j(5, 10);
This works :)
function f($str, $delimiter = ';')
{
$strargs = explode($delimiter, $str);
$args = array();
foreach($strargs as $item)
eval("\$args[] = " . $item. ";");
// $args contains all arguments
print_r($args);
}
Check it:
f("6;array(8,9);array(array(1,0,8), 5678)");
Most of the answers assume, that everything is nicely separated with coma ",", but it's not always the case. For example there could be different variable types, even strings with coma's.
$values = "123, 'here, is, a, problem, that, can\'t, be, solved, with, explode() function, mkay?'";
This can be handled with eval() and dot's "..." args retrieval in php 7.
function helper_string_args(...$args) {
return $args;
}
$func = "\$values = \\helper_string_args($values);";
try {
eval($func);
} catch (Exception $e) {
var_dump($e);
exit;
}