Categories
PHP

Object Cloning in PHP

Object cloning is the act of making a copy of an object. Cloning in PHP is done by making a shallow copy of the object. This means that internal objects of the cloned object will not be cloned, unless you explicitly instruct the object to clone these internal objects too, by defining the magic method __clone().

In simple words,

Cloning is used to create a genuine copy of an object. Assigning an object to another variable does not create a copy – rather, it creates a reference to the same memory location as the object:

$o = new stdclass;
$o->a = 'b';
$o->b = 'c';

$o2 = $o;
$o2->a = 'd';

var_dump($o);
var_dump($o2);

$o3 = clone $o;
$o3->a = 'e';
var_dump($o);
var_dump($o3);

This example code will output the following:

object(stdClass)#1 (2) {
  ["a"]=>
  string(1) "d"
  ["b"]=>
  string(1) "c"
}
object(stdClass)#1 (2) {
  ["a"]=>
  string(1) "d"
  ["b"]=>
  string(1) "c"
}
object(stdClass)#1 (2) {
  ["a"]=>
  string(1) "d"
  ["b"]=>
  string(1) "c"
}
object(stdClass)#2 (2) {
  ["a"]=>
  string(1) "e"
  ["b"]=>
  string(1) "c"
}

If you don’t utilize the __clone method, the internal objects of the new object will be references to the same objects in memory as the internal objects of the original object that was cloned.

// in this example the internal member $_internalObject of both objects
// reference the same instance of stdClass in memory.
class CloneableClass
{
    private $_internalObject;

    public function __construct()
    {
        // instantiate the internal member
        $this->_internalObject = new stdClass();
    }
}

$classA = new CloneableClass();
$classB = clone $classA;

// in this exampe the internal member $_internalObject of both objects
// DON'T reference the same instance of stdClass in memory, but are inividual instances
class CloneableClass
{
    private $_internalObject;

    public function __construct()
    {
        // instantiate the internal member
        $this->_internalObject = new stdClass();
    }

    // on clone, make a deep copy of this object by cloning internal member;
    public function __clone()
    {
        $this->_internalObject = clone $this->_internalObject;
    }
}

$classA = new CloneableClass();
$classB = clone $classA;

Use cases for cloning would for instance be a case where you don’t want outside objects to mess with the internal state of an object.

Let’s say you have a class User with a internal object Address.

class Address
{
    private $_street;
    private $_streetIndex;
    private $_city;
    // etc...

    public function __construct( $street, $streetIndex, $city /* etc.. */ )
    {
        /* assign to internal values */
    }
}

class User
{
    // will hold instance of Address
    private $_address;

    public function __construct()
    {
        $this->_address = new Address( 'somestreet', '1', 'somecity' /* etc */ );
    }

    public function getAddress()
    {
        return clone $this->_address;
    }
}

For arguments sake, let’s say you don’t want outside objects to mess with the internal Address of User objects, but you do want to be able to give them a copy of the Address object. The above example illustrates this. The getAddress method returns a clone of the address object to calling objects. This means that if the calling object alters the Address object, the internal Address of User will not change. If you didn’t give a clone, then the outside object would be able to alter the internal Address of User, because a reference is given by default, not a clone.

An object copy is created by using the clone keyword (which calls the object’s __clone() method if possible).  An object’s __clone() method cannot be called directly.

$copy_of_object = clone $object;

Creating a copy of an object with fully replicated properties is not always the wanted behavior. If your object holds a reference to another object which it uses and when you replicate the parent object you want to create a new instance of this other object so that the replica has its own separate copy.

class SubObject
{
    static $instances = 0;
    public $instance;

    public function __construct() {
        $this->instance = ++self::$instances;
        echo "SubObject construct\n";
    }

    public function __clone() {
        $this->instance = ++self::$instances;
        echo "SubObject clone\n";
    }
}

class MyCloneable
{
    public $object1;
    public $object2;

    function __clone()
    {
        // Force a copy of this->object, otherwise
        // it will point to same object.
        $this->object1 = clone $this->object1;
        echo "MyCloneable clone\n\n";
    }
}

$obj = new MyCloneable();
echo "new MyCloneable() -- Done with MyCloneable \n\n";

echo "calling new SubObject() \n";
$obj->object1 = new SubObject();
echo "new SubObject() -- Done with SubObject1 \n";
echo "calling new SubObject() \n";
$obj->object2 = new SubObject();
echo "new SubObject() -- Done with SubObject2 \n\n";

echo "calling clone of MyCloneable object \n";
$obj2 = clone $obj;

print("Original Object:\n");
print_r($obj);

print("Cloned Object:\n");
print_r($obj2);

resulting to

new MyCloneable() -- Done with MyCloneable

calling new SubObject()
SubObject construct
new SubObject() -- Done with SubObject1
calling new SubObject()
SubObject construct
new SubObject() -- Done with SubObject2

calling clone of MyCloneable object
SubObject clone
MyCloneable clone

Original Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 1
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )
)

Cloned Object:
MyCloneable Object
(
    [object1] => SubObject Object
        (
            [instance] => 3
        )

    [object2] => SubObject Object
        (
            [instance] => 2
        )
)
'Coz sharing is caring
Categories
App PHP

How To Get Multiple Facebook Like Buttons

In this article, I will attempt to be as clear as possible. Again, my technical expertise may not be up to par with, say, Mark Zuckerberg, but I will do my very best to keep the terminology and code as accurate as possible.

First Things, First:
Getting The Facebook Like Button

Before you get the code for a Facebook Like button from developers.facebook, I recommend you set up your website as a Facebook application. This will give you valuable tools to manage your Facebook plugins (such as analytics tools, which allows you to see how users are interacting with your buttons, and moderating tools for the comment box (which, by the way, you can get the code for here)

Setting up your website as a Facebook application can seem a little daunting. I found this article and it walked me through step by step through the entire process. Tutorial: How to Create a Facebook Application to Get an App ID for your Website or Blog.
I recommend you get the code for the Like button AFTER you set up your site as a Facebook application.

Place Facebook Like Button Code On Your Website

I didn’t want to glaze over this part, just in case.When you retrieve your Facebook like button code from the developers.facebook button generator, you will get two codes:

The code in the first box is the main Facebook plugin code that applies to ALL Facebook plugins on that particular page (including comment box, etc). This code will go right after the opening < body > tag of your page. You only need this code once per page regardless of how many like buttons or other comment boxes you have on that particular page.

The code in the second box, is the code to display the actual like button.This is the code you will post wherever you want your like button to appear.

Notice that there are some elements that need customizing:On the first box, fifth line:

js.src = \"//connect.facebook.net/en_US/all.js#xfbml=1";

If you generated the button code after your made your website a facebook object (Tutorial: How to Create a Facebook Application to Get an App ID for your Website or Blog), facebook will automatically insert your website’s id here and so that line will read:

js.src = \"//connect.facebook.net/en_US/all.js#xfbml=1";

But, if you didn’t, then you will need to enter this manually (that is, if you got an ID in the first place).

Also, on the second box, the url will be customized. You can leave that as anything for now, I will show you below what this URL should be in order for each like button to reference different items.

Meta Tags

Now that you have your website set up as a Facebook application, and you’ve generated a like button from the developers.facebook page, let me show you how to place it in your code.
The first thing you have to know is that the code you generated from the facebook like button doesn’t have the meta tags included.meta tags are a set of instructions for the browser, they go in between the < head > tags. Facebook plugins use meta tags to figure out what information to display on Facebook when someone Likes or Comments on your post. The meta tags we will be working with look like this:

< head >
< meta property="fb:app_id" content="YOUR-APP-ID"/>
< meta property="fb:admins" content="USER_ID,USER_ID"/ >
< meta property="og:title" content="Page Title"/>
< meta property="og:type" content="object Type"/>
< meta property="og:site_name" content="The Name You want to display as the main webpage"/ >
< meta property="og:url" content="http://www.mydomain.com/page-url"/>
< meta property="og:image" content="http://URL-TO-IMAGE"/>
< meta property="og:description" content="Description of page content"/>
< /head>

fb:app_id is the id# given to you by facebook when you created an website object.
fb:admins is the facebook user id of whoever you wish to be able to be a moderator of your facebook plugins (you can enter multiple ids, separated by commas). This id is usually in the url of your facebook homepage.
og:title is the title that displays on facebook when button is clicked.
og:type Facebook has a predefine list of object types that can be found here But you can go with “website”
og:site_name this is the website title (not article title) that will display when someone clicks the link (ie. your website name).
og:url this is the url of the current page
og:img the url of the image facebook will display
og:description the description facebook will display

Here’s why multiple like buttons on one page becomes tricky: Each html or php page can only have one of each Meta Tag. Meaning, when you define:

<meta property="og:title" content="Title To Display "/ >

Every like button on the page will reference that title. The same with the rest of the tags. And while some of the tags do, indeed, remain the same regardless of the content (such as the fb:app_id, fb:admins, og:site_name) others (like og:title, og:image, og:url, and og:description), should be specific to what the link is referring to.

The solution is simple: every like button needs a separate set of meta tags.
The execution is also, surprisingly simple: every like button needs to reference a separate html or php document that contains the content specific meta tags.

Multiple Like Buttons For Different Items

Step 1: Modify your HTML tags so that it doesn’t interfere with the Facebook meta tags:So, instead of < html > < /html > , use

< html xmlns:og="http://ogp.me/ns#" >
< /html >

Step 2:Your main page (the page that contains the multiple like buttons) can contain the meta tags for the main article, or general metatags for the website. Otherwise, the like button you want to display the information displayed in these meta tags will need to contain the url of the page.

Step 3: For EACH article/item that you want a like button for, create a separate html or php page (unless the article already has a separate page– in that case, place the content specific meta tags on that page.).On that HTML or PHP page, you will need to include the meta tags in between the < head > < /head > tags.

So the HTML it should look something like this:

< html xmlns:og="http://ogp.me/ns#" >
< head >
< title > This is your Standard Page Title < /title >
< meta property="fb:app_id" content="YOUR-APP-ID"/>
< meta property="fb:admins" content="USER_ID,USER_ID"/ >
< meta property="og:title" content="Page Title"/>
< meta property="og:type" content="website"/>
< meta property="og:site_name" content="The Name You want to display as the main webpage"/ >
< meta property="og:url" content="http://www.mydomain.com/page-url"/>
< meta property="og:image" content="http://URL-TO-IMAGE"/>
< meta property="og:description" content="Description of page content"/>
< /head >
< body >
< /body >
< /html >

(include doctype, if needed, before the html start tag)

Step 4: Now that you have an HTML or PHP page with content unique meta tags in the head, you will need to edit the code of EACH like button so that it references the page that contains it’s meta tags.
The code for the individual Like buttons looks like this (may vary depending on the style you chose from the facebook button generator, just focus on the href tag information):

The url within this href tag MUST match the url in the meta tag og:url otherwise, the like button wont reference the correct information. Remember, the url in the meta tag og:url is the url of the html or php page that contains the meta tag.

< fb:like href="full URL of page that contains the meta tags related to THIS like button" layout="button_count" show_faces="false" width="240" height="40" action="like" colorscheme="light" >

Also, don’t forget the Facebook plugin script (the code in the first box that is generated when you make a button) that goes right under the opening body tags of each page that has like buttons (again, just one is needed per page).

One thing I want to mention, because like I said I spent hours gnawing my eyes out over this. First, code one or two like buttons at a time and double, triple check your code. One tiny error can cause the entire plugin to not work properly. If you code a crap load of like buttons at once and you have an error, it will likely take forever to go through each one and fix them individually. So perfect your code, then copy and paste and customize.

Thankfully, Facebook developers created a debugger that will let you know what Facebook can see from your link. Basically, you enter the url of the site you want to check (in your case, the URL with the meta tags of the like button you want to test) and the debugger will let you know if there are any errors. Listen to it. I didn’t, for a while. I kept thinking, this is obviously wrong because I can’t find the error it’s pointing to. But nope, it ended up being right and I wasted time resisting technology that is far smarted than I.

'Coz sharing is caring