Asked  7 Months ago    Answers:  5   Viewed   31 times

I can't seem to get any consistent info on this. Different sources appear to say different things and the venerable php.net itself (appears) not to explicitly state this - although, I must admit, I only had a quick look.

In cases where I am passing around 'heavy' objects, I need to pass by reference, but I don't want to keep typing:

function foo(TypeName& $obj)

if I can get away with simply

function foo(TypeName $obj)

So what does the standard say?

 Answers

62

Objects are passed (and assigned) by reference. No need to use address of operator.

Granted what I typed is an oversimplification but will suit your purposes. The documentation states:

One of the key-points of PHP5 OOP that is often mentioned is that "objects are passed by references by default". This is not completely true. This section rectifies that general thought using some examples.

A PHP reference is an alias, which allows two different variables to write to the same value. As of PHP5, an object variable doesn't contain the object itself as value anymore. It only contains an object identifier which allows object accessors to find the actual object. When an object is sent by argument, returned or assigned to another variable, the different variables are not aliases: they hold a copy of the identifier, which points to the same object.

For a more detailed explanation (explains the oversimplification as well as identifiers) check out this answer.

Wednesday, March 31, 2021
 
aslum
answered 7 Months ago
86

You should point to your vendor/autoload.php at Settings | PHP | PHPUnit when using PHPUnit via Composer.

This blog post has all the details (with pictures) to successfully configure IDE for such scenario: http://confluence.jetbrains.com/display/PhpStorm/PHPUnit+Installation+via+Composer+in+PhpStorm

Related usability ticket: http://youtrack.jetbrains.com/issue/WI-18388

P.S. The WI-18388 ticket is already fixed in v8.0

Wednesday, March 31, 2021
 
ojrac
answered 7 Months ago
79

On Mac OS X environment variables available in Terminal and for the normal applications can be different, check the related question for the solution how to make them similar.

Note that this solution will not work on Mountain Lion (10.8).

Saturday, May 29, 2021
 
Nate
answered 5 Months ago
51

It's by value according to the PHP Documentation.

By default, function arguments are passed by value (so that if the value of the argument within the function is changed, it does not get changed outside of the function). To allow a function to modify its arguments, they must be passed by reference.

To have an argument to a function always passed by reference, prepend an ampersand (&) to the argument name in the function definition.

<?php
function add_some_extra(&$string)
{
    $string .= 'and something extra.';
}

$str = 'This is a string, ';
add_some_extra($str);
echo $str;    // outputs 'This is a string, and something extra.'
?>
Saturday, June 5, 2021
 
turik
answered 5 Months ago
68

Technically they're copied, because when you use make, you are allocating something on the heap, so it's technically a pointer behind the scenes. But the pointer type is not exposed, so they can be thought of as a reference type.

EDIT: From the spec:

The built-in function make takes a type T, which must be a slice, map or channel type, optionally followed by a type-specific list of expressions. It returns a value of type T (not *T). The memory is initialized as described in the section on initial values.

A channel must be initialized before it can be used. Make does this, so it can be used as a reference type.

What this basically means is that you can pass it into a function and write to or read from it. The general rule of thumb is if you use make, new or &, you can pass it to another function without copying the underlying data.

So, the following are "reference" types:

  • slices
  • maps
  • channels
  • pointers
  • functions

Only data types (numbers, bools and structs, etc) are copied when passing into a function. Strings are special, because they're immutable, but not passed by value. This means that the following won't work as expected:

type A struct {
    b int
}
func f(a A) {
    a.b = 3
}
func main() {
    s := A{}
    f(s)
    println(s.b) // prints 0
}
Saturday, September 4, 2021
 
Shinobi_Atobe
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :