From Ruby to PHP

Here in my blog, I’ve been chronicling my journey to learn PHP, coming from Ruby as my first programming language. It’s been a interesting journey so far; while PHP and Ruby share some similarities as scripting languages, the other components and technologies surrounding them are different, at least for me as a beginner in PHP. I wanted to write a blog post about the certain steps I’ve made, including outlining the resources I’ve found and the stacks I’ve been learning in this transition. If you’re coming from Ruby to PHP, I hope this post can help you get started.

After I got the building blocks of PHP out of the way, learning the new syntax through various resources (including Codecademy) and books, I took the next step in my learning by re-envisioning a project I worked on during my time at Flatiron called GuideMe. My choice to take a project I had already done was for a few reasons: The models and their relationships have already been imagined, so I could jump right into learning a new ORM more easily; I also have all of the styling (Bootstrap and otherwise) set up, which would make my project look prettier during the beginning stages of coding it; And, in this case, GuideMe is a relatively uncomplicated concept that would allow me to concentrate on learning the stacks. I think all of this helps for a first major project in another language.

With the help of the incredibly patient and helpful Matthew Turland, whose been a great resource during my journey into PHP, I came up with a strategy on how to tackle this project. First I should note that it is my impression, given my experience (and this could be from my then limited exposure working with the technologies Flatiron focused on), Ruby is relatively contained: to get the job done, there are a few well constructed technologies that basically everyone uses (for example, Bundler, ERB, Rails, or Sinatra). However, in the PHP world, there are many choices of tools to use (different dependency management strategies, many different frameworks, and various templating options).

I decided to work with things I found relatively similar to what I’ve been working with in Ruby, simply because these Ruby technologies work well. I’m going to go through each part of my stack I’m currently working on and discuss what makes them great for Rubyists turned PHPists.

Composer

I’ll admit I chose Composer because it’s what we’re currently using at my company. It’s relatively new, but the documentation is solid and it’s not unlike Bundler for managing your Ruby gems. Installing composer within your project directory creates a composer.json file, where you can require all of your dependencies and files for autoload.

Doctrine ORM

Doctrine ORM is a DataMapper ORM that I chose to learn because, again, the documentation is pretty straightforward. They have a tutorial that’s helpful in walking you through setting up a simple project. With Doctrine, you create entities, or models, that serve to map your objects onto a database. Each model is a class, and within that class, you can map your object’s relations to other objects. Below is my model for my Topic object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use Doctrine\Common\Collections\ArrayCollection;
/**
 * @Entity @Table(name="topics")
 **/
class Topic {
  /** @Id @Column(type="integer") @GeneratedValue **/
  protected $id;
  /**
   * @Column(type="string")
   * @var string
   */
  protected $title;
  /**
   * @Column(type="string")
   * @var string
   */
  protected $description;
  /**
   * @ManyToOne(targetEntity="User", inversedBy="topics")
   **/
  protected $user;
  /**
   * @OneToMany(targetEntity="Suggestion", mappedBy="topic")
   * @var Suggestion[]
   **/
  protected $suggestions;
  /**
   * @ManyToMany(targetEntity="Tag", inversedBy="topics")
   * @JoinTable(name="topics_tags")
   **/
  protected $tags;

  public function __construct() {
    $this->tags = new ArrayCollection();
    $this->suggestions = new ArrayCollection();
  }

  public function getId() {
    return $this->id;
  }

  public function getTitle() {
    return $this->title;
  }

  public function setTitle($title) {
    $this->title = $title;
  }

  public function getDescription() {
    return $this->description;
  }

  public function setDescription($description) {
    $this->description = $description;
  }

  public function getUser() {
    return $this->user;
  }

  public function setUser($user) {
    $this->user = $user;
  }

  public function getSuggestions() {
    return $this->suggestions;
  }

  public function setSuggestions($suggestions) {
    $this->suggestions = $suggestions;
  }

  public function getTags() {
    return $this->tags;
  }

  public function setTags($tags) {
    $this->tags = $tags;
  }
}

Let’s say I have a page that displays all of the topics. With my above model in place, I can then iterate through $topics (managed by the entityManager class, as outlined here) like so:

1
2
3
4
5
6
foreach ($topics as $topic) {
  echo $topic->getTitle()
  echo $topic->getDescription()
  echo $topic->getUser()->getName()
  ...
}

Slim Framework

Slim is a lightweight framework inspired by Sinatra. The documentation for it is great, and for those that love Sinatra, it’s familiar.

Once Slim is required by Composer (so easy!), within the home directory of your project, set up an index.php file (like app.rb in Sinatra), where you’ll keep your routes and instantiate a new Slim object (your app). For sake of clarity, depending on the size of the project, you can keep index.php as the runner file to run your application, and require other route files that you can organize elsewhere (I have a routes directory I keep them all in, and each file corresponds with an object; while called routes, I like to think of them as Controllers).

Here’s an example of a route in Slim, taken from the documentation. Not unlike Sinatra at all!

1
2
3
$app->get('/hello/:name', function ($name) {
    echo "Hello, $name";
});

There are also full-stack frameworks within the PHP world. The two most popular ones that have evolved nicely with the language are Symfony and Zend.

Templating

There are many options for templating in PHP. While both Twig and Smarty are quite popular, I wanted to go with something that didn’t require learning another markdown language, but instead uses PHP; essentially I wanted the ERB equivalent. Savant3 is incredibly easy to use. The bulk of what it does is pass your object to an instance of the Savant class. Here is my route for displaying one topic by id. I create a new instance of the Savant class, $tpl, pass my already collected instance of Topic ($topic) to it, and then render it through Savant’s display() method:

1
2
3
4
5
6
7
8
9
$app->get('/topics/:id', function($id) use($entityManager) {

  $topic = $entityManager->find("Topic", (int)$id);

  $tpl = new Savant3();
  $tpl->topic = $topic;
  $tpl->display('views/topics/show.tpl.php');

});

In my show.tpl.php file, I refer to $tpl->topic as $this->topic. Passing the object like this as well passes all of its class functions, like getTitle(), getUser(), etc.

Conclusion

PHP has a lot of tools out there for web development; I chose all of these because they embody characteristics of similar tools in Ruby that I love. I’m open to any suggestions for other great tools from those who code in both Ruby and PHP! :)

Comments