Is there a PHP function for swapping the values of two variables?
Asked Answered
M

20

94

Say for instance I have ...

$var1 = "ABC"
$var2 = 123

and under certain conditions I want to swap the two around like so...

$var1 = 123
$var2 = "ABC"

Is there a PHP function for doing this rather than having to create a 3rd variable to hold one of the values then redefining each, like so...

$var3 = $var1
$var1 = $var2
$var2 = $var3

For such a simple task its probably quicker using a 3rd variable anyway and I could always create my own function if I really wanted to. Just wondered if something like that exists?

Update: Using a 3rd variable or wrapping it in a function is the best solution. It's clean and simple. I asked the question more out of curiosity and the answer chosen was kind of 'the next best alternative'. Just use a 3rd variable.

Mundt answered 22/8, 2010 at 13:58 Comment(2)
You can use xor too, like... b = a xor b, a = a xor b, b = a xor b should do the trick... Dunno if theres a function, I'm not good with PHP.Begat
These answers resemble some sort of an obfuscation contest.Emarie
A
134

TL;DR

There isn't a built-in function. Use swap3() as mentioned below.

Summary

As many mentioned, there are multiple ways to do this, most noticable are these 4 methods:

function swap1(&$x, &$y) {
    // Warning: works correctly with numbers ONLY!
    $x ^= $y ^= $x ^= $y;
}
function swap2(&$x, &$y) {
    list($x,$y) = array($y, $x);
}
function swap3(&$x, &$y) {
    $tmp=$x;
    $x=$y;
    $y=$tmp;
}
function swap4(&$x, &$y) {
    extract(array('x' => $y, 'y' => $x));
}

I tested the 4 methods under a for-loop of 1000 iterations, to find the fastest of them:

  • swap1() = scored approximate average of 0.19 seconds.
  • swap2() = scored approximate average of 0.42 seconds.
  • swap3() = scored approximate average of 0.16 seconds. Winner!
  • swap4() = scored approximate average of 0.73 seconds.

And for readability, I find swap3() is better than the other functions.

Note

  • swap2() and swap4() are always slower than the other ones because of the function call.
  • swap1() and swap3() both performance speed are very similar, but most of the time swap3() is slightly faster.
  • Warning: swap1() works only with numbers!
Academic answered 24/10, 2014 at 13:37 Comment(9)
Changed the answer to this one since the question seems to get a lot of attention and you've bench marked them. swap3 is basically the same as the original question wrapped up in function. Proof that simplicity is often better, even if it means extra lines!Mundt
Yep, I upvote your summary too. But you can remove swap1, it does some real bulshit.Arabia
Swap2 is clearly best for readability/writability. Swap1 is just presumptuous and Swap3 is the 'non swapping' way to do it. Obviously any option is okay if you make your own wrapper function that works how you want, as swap(&$a,&$b) can be useful.Volatilize
Swap1 was perfect for me as all I wanted was to swap bytes if one was bigger than the otherDillondillow
@StevenByrne Note that swap1 only works with numbers!Academic
Yes, which was perfect for my use (number of bits (ints) needing to be swapped)Dillondillow
Why not remove swap1 if it works only with numbers? It's such a big caveat and this function has no advantage over just swapping as in swap3Twittery
for what it's worth swap2() can now be rewritten per @Pawel Dubiel's answer below and is much faster than it was when those benchmarks were written. I ran some benchmarks of my own and over 1 million iterations it only took 0.01 seconds longer than swap3() which is of course negligible. Also, [$a, $b] = [$b, $a]; looks great.Oleson
Warning: swap1 does not work if $x and $y are the same variable.Thurmanthurmann
I
106

There's no function I know of, but there is a one-liner courtesy of Pete Graham:

list($a,$b) = array($b,$a);

not sure whether I like this from a maintenance perspective, though, as it's not really intuitive to understand.

Also, as @Paul Dixon points out, it is not very efficient, and is costlier than using a temporary variable. Possibly of note in a very big loop.

However, a situation where this is necessary smells a bit wrong to me, anyway. If you want to discuss it: What do you need this for?

Impossible answered 22/8, 2010 at 13:59 Comment(8)
+1 - found the same, and agree, not sure I like it either - using a temp variable is considerably better - as is writing your own swap method if you find yourself doing this often.Paladin
using it to switch 2 values in a field if some plonker puts values in the form around the wrong way. The values are fairly restricted to what they can be so its easy enough to figure out whether they should have been around the other way. More of a usability thing so it helps out those that aren't great on a computer... or just having a bad moment. :-)Mundt
as this is the accepted answer for a question that might educate others, it's worth pointing out just how inefficient this is. You're asking PHP to create an array, only to immediately discard it. I benchmarked this approach against using a temporary variable, and found that using a temp variable is over 7 times faster. I would also argue it makes the intent clearer too, as it's a common idiom!Zandra
@Paul great information about the benchmark - it's meaningless for one or two operations, but will make a difference in loops. Editing the answer to reflect that.Impossible
@paul figured as much, simplicity usually is. Good to see an actual benchmark.Mundt
And since this answerer is sceptical, what made me Google whether PHP had a built-in swap() is iterating through an array where the keys hold value - e.g. they indicate columns in a database, and the values indicate values. However if there isn't a pair, just a value, then you can have the option to use the value as the key (swap) and use a default value. Since in my example I don't need to keep the key, it's not really essential, but if I did need to keep the array index, I'd rather use a (bult-in) swap() call than creating a stupidly named temporary. But, this isn't built-in...Volatilize
Link in answer is dead - 404 File not found.Initiation
It's also worth noted that you can swap more than 2 variables with this code snippet: $x = 'x'; $y = 'y'; $z = 'z'; list($x, $y, $z) = [$y, $z, $x]; will return $x = 'y'; $y = 'z'; $z = 'x';. Useful for stack ordering, if you don't already have an array for this :-)Ptero
S
78

Yes, there now exists something like that. It's not a function but a language construct (available since PHP 7.1). It allows this short syntax:

 [$a, $b] = [$b, $a];

See "Square bracket syntax for array destructuring assignment" for more details.

Shantae answered 25/9, 2016 at 23:37 Comment(4)
My vote is for this one because: It is easily done inline, and it is only one line (I did not test to see if it runs faster than the function call options.) My programming time is usually more valuable than the computer time.Maiocco
This is essentially the same as swap2() in the accepted answer, ie list($x, $y) = array($y, $x);Shrieval
@Shrieval I agree but language construct wins over functions call.Dynast
@AhsaanYousuf php.net/list "Like array(), this is not really a function, but a language construct. "Conspecific
S
17

It is also possible to use the old XOR trick ( However it works only correctly for integers, and it doesn't make code easier to read.. )

$a ^= $b ^= $a ^= $b;
Shantae answered 23/7, 2012 at 16:22 Comment(1)
If you use it with words, containing same parts, it returns funny and unexpected result: ideone.com/NGQVYHSalable
C
11

Yes, try this:

// Test variables
$a = "content a";
$b = "content b";

// Swap $a and $b
list($a, $b) = array($b, $a);

This reminds me of python, where syntax like this is perfectly valid:

a, b = b, a

It's a shame you can't just do the above in PHP...

Carcinomatosis answered 22/8, 2010 at 14:0 Comment(1)
you can, as above. [$a, $b] = [$b, $a]Flump
W
7

Another way:

$a = $b + $a - ($b = $a);
Wehrmacht answered 29/8, 2013 at 7:36 Comment(0)
A
7

For numbers:

$a = $a+$b;
$b = $a-$b;
$a = $a-$b;

Working:

Let $a = 10, $b = 20.

$a = $a+$b (now, $a = 30, $b = 20)

$b = $a-$b (now, $a = 30, $b = 10)

$a = $a-$b (now, $a = 20, $b = 10 SWAPPED!)

Autointoxication answered 28/10, 2013 at 22:40 Comment(3)
This works only for numbers and is not a build-in PHP-function. The OP asked for a more general approach and for a predefined function.Monumentalize
You are right, missed it looking at all the other answers and implementations.Autointoxication
If your numbers are too big, this method could overflow.Maiocco
S
6
list($var1,$var2) = array($var2,$var1);
Shaeshaef answered 22/8, 2010 at 14:0 Comment(0)
C
4

This one is faster and needs lesser memory.

function swap(&$a, &$b) {
    $a = $a ^ $b;
    $b = $a ^ $b;
    $a = $a ^ $b;
}

$a = "One - 1";
$b = "Two - 2";

echo $a . $b; // One - 1Two - 2

swap($a, $b);

echo $a . $b; // Two - 2One - 1

Working example: http://codepad.viper-7.com/ytAIR4

Cordite answered 24/7, 2013 at 10:34 Comment(1)
A note to all: this function only works properly in all cases if $a and $b are the same length, as per @m13rJudsonjudus
C
4

another simple method

$a=122;
$b=343;

extract(array('a'=>$b,'b'=>$a));

echo '$a='.$a.PHP_EOL;
echo '$b='.$b;
Crigger answered 5/5, 2014 at 12:5 Comment(0)
C
2

Here is another way without using a temp or a third variable.

<?php
$a = "One - 1";
$b = "Two - 2";

list($b, $a) = array($a, $b);

echo $a . $b;
?>

And if you want to make it a function:

    <?php
    function swapValues(&$a, &$b) {
         list($b, $a) = array($a, $b);
     }
    $a = 10;
    $b = 20;
    swapValues($a, $b);

    echo $a;
    echo '<br>';
    echo $b;
    ?>
Cuff answered 25/9, 2013 at 6:5 Comment(0)
G
2

Thanks for the help. I've made this into a PHP function swap()

function swap(&$var1, &$var2) {
    $tmp = $var1;
    $var1 = $var2;
    $var2 = $tmp;
}

Code example can be found at:

http://liljosh.com/swap-php-variables/

Griseofulvin answered 28/10, 2013 at 13:38 Comment(0)
E
2

3 options:

$x ^= $y ^= $x ^= $y; //bitwise operators

or:

list($x,$y) = array($y,$x);

or:

$tmp=$x; $x=$y; $y=$tmp;

I think that the first option is the fastest and needs lesser memory, but it doesn’t works well with all types of variables. (example: works well only for strings with the same length)
Anyway, this method is much better than the arithmetic method, from any angle.
(Arithmetic: {$a=($a+$b)-$a; $b=($a+$b)-$b;} problem of MaxInt, and more...)

Functions for example:

function swap(&$x,&$y) { $x ^= $y ^= $x ^= $y; }
function swap(&$x,&$y) { list($x,$y) = array($y,$x); }
function swap(&$x,&$y) { $tmp=$x; $x=$y; $y=$tmp; }

//usage:
swap($x,$y);
Evanston answered 16/1, 2014 at 16:35 Comment(2)
It works (if they have the same length). Tested right now, on PHP5.5Evanston
code: function swap(&$x,&$y) {$x ^= $y ^= $x ^= $y;} $a="aaa"; $b="bbb"; swap($a,$b); echo $a,$b;Evanston
I
0

If both variables are integers you can use mathematical approach:

$a = 7; $b = 10; $a = $a + $b; $b = $a - $b; $a = $a - $b;

Good blog post - http://booleandreams.wordpress.com/2008/07/30/how-to-swap-values-of-two-variables-without-using-a-third-variable/

Incrust answered 31/1, 2013 at 21:56 Comment(0)
R
-2

Yes I know there are lots of solutions available, but here is another one. You can use parse_str() function too. Reference W3Schools PHP parse_str() function.

<?php
    $a = 10;
    $b = 'String';

    echo '$a is '.$a;
    echo '....';
    echo '$b is '.$b;

    parse_str("a=$b&b=$a");

    echo '....After Using Parse Str....';

    echo '$a is '.$a;
    echo '....';
    echo '$b is '.$b;

?>

DEMO

Radical answered 11/3, 2016 at 10:11 Comment(1)
Why the hell would you do that ... and what about the case, when $b contains something like b&a=abc?Kalahari
O
-2

I checked all solutions after that i came up with another solution that was not found anywhere. my logic is simple. i used PHP variable ref. pattern. means $$. you can read more about this by this link https://www.php.net/manual/en/language.variables.variable.php

$a =12;$b="ABC";
$$a =$b;
$$b= $$a.$a;
echo " a = $a and b=$b <br>now after reverse.<br>";
echo $$b;

//output : abc12

If you do not want to use the method then you can try this also

$a =10; $b=15;

echo  " a = $a , b= $b \n";  // a= 10 , b=15

$a = $a ^ $b; echo "a= 5 \n" ;
$b = $a ^ $b; echo "b= 10 \n" ;
$a = $a ^ $b; echo "a= 15 \n" ;

echo  " a = $a , b= $b";  // a= 15 , b=10
Oly answered 16/6, 2022 at 18:19 Comment(3)
This code makes no senseLabio
Although working and interesting - I didn't know about Variable Variables until reading this, although now I wish I never found out about them - the code is impractical and there's no benefit over simply using a variable called $temp :)Shifra
@YourCommonSense how you can say this ? can you explain? This is an interview Question's answer. This question was asked many times by some developers as well as by me. May be this is not a platform to share interview Q. but may be it can be a solution of a problem for someone.Oly
S
-3
$a = 'ravi';

$b = 'bhavin';

$a = $b.$a;

$b = substr($a,strlen($b),strlen($a));

$a = substr($a,0,strlen($a)-strlen($b));

echo "a=".$a.'<br/>'.'b='.$b;
Scramble answered 10/4, 2017 at 13:35 Comment(0)
A
-4

another answer

$a = $a*$b;
$b = $a/$b;
$a = $a/$b;
Algology answered 27/3, 2014 at 6:1 Comment(0)
F
-4
<?php

swap(50, 100);

function swap($a, $b) 
{
   $a = $a+$b;
   $b = $a - $b;
   $a = $a - $b;
   echo "A:". $a;
   echo "B:". $b;
 }
?>
Flatling answered 31/7, 2017 at 16:9 Comment(2)
While answers are always appreciated, this question was asked 6 years ago, and already had an accepted solution. Please try to avoid 'bumping' questions to the top by providing answers to them, unless the question was not already marked as resolved, or you found a new and improved solution to the problem. Also remember to provide some context surrounding your code to help explain it. Check out the documentation on writing great answers for some tips on how to make your answers count :)B
There is NOTHING WRONG with posting an answer to an old question. The fact that an answer has been accepted should IN NO WAY discourage users from posting unique, valuable insights on Stack Overflow. Note though that previous answers already recommended using addition then subtraction in this manner -- so this answer brings no new value to this page.Soundboard
L
-11
$a=5; $b=10; $a=($a+$b)-$a; $b=($a+$b)-$b;
Lemures answered 24/7, 2013 at 9:44 Comment(1)
This doesn't work, both a and b would be 10. (10+10)-10 = 10Physiotherapy

© 2022 - 2024 — McMap. All rights reserved.