28
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【PHP入門】RubyエンジニアがPHPを勉強し始めるときに見る記事

Last updated at Posted at 2020-12-06

この記事 is 何

RubyエンジニアがPHPを勉強し始めるときに見る、PHPの入門記事です。

動機

今までRubyをやってきていて、PHPを使うことになったというケースは少なくないと思っています。
特に実務未経験の方々では、このケースが多いのではないでしょうか?
というのは、実務未経験が学習している言語は、Rubyがファーストチョイスである一方で、PHPを使う企業は少なくないためです。
ちなみに、僕もそのケースでした。
そういう方々が過度に不安を持ったりせず、スムーズに転向できるようにしたいと思い、この記事を書きました。

この記事の主なターゲット

  • 今までRubyを勉強してたが、PHPを使うことになった人
  • というか半年前の自分

この記事で書くつもりのないこと

  • 技術選定時・初学者が学ぶ言語としてRuby or PHPはどっちが良いのかということ
  • 網羅的・辞書的にRubyとPHPを比較した結果
  • RubyとPHPの文法の正確な対応関係

学習のし始め

RubyからPHPへの転向コスト

Rubyをちゃんと習得できた方であれば、転向・学習コストにおいて問題はほぼ起きないと思います。
文法を調べながらとりあえず書き始められる、というレベルに達するには半日〜3日程度の勉強で済むと思います。

文法を調べるときに何を使うか

php.net
PHPは公式ドキュメントが神なので、基本的にこのサイトを見ればPHPの文法的な解決してくれるはずです。

Screen Shot 2020-11-15 at 18.55.08.png

ググラビリティも良好で、「array_merge php」などと検索すれば公式ドキュメントが先頭に出てくれます。

本題

動作確認バージョン
$ php -v
PHP 7.3.11 ...

$ ruby -v
ruby 2.6.3p62 ...

基本的なオブジェクトの概念

出力

Ruby PHP
改行なし出力 print echo
型情報付き出力 p var_dump()
配列に対し改行付き出力 puts echo, PHP_EOL

Rubyのprintは、PHPでいうとechoに近いです。
Rubyのpは、PHPでいうとvar_dumpに近いです。

Rubyのputsは?と言われると、対応したものはありません。
echoPHP_EOLを組み合わせる必要があります。

objects/print.rb
print 'sample!'
# sample!

sample_array = [1, 'sample']
print sample_array
# [1, "sample"]

p sample_array
# [1, "sample"]

puts sample_array
# 1
# sample
objects/class.php
<?php
echo 'sample!';
// sample!

$sample_array = [1, 'sample'];
echo $sample_array;
// Array

var_dump($sample_array);
// array(2) {
//   [0]=>
//   int(1)
//   [1]=>
//   string(6) "sample"
// }

foreach ($sample_array as $value) {
    echo $value . PHP_EOL;
}
// 1
// sample

プリミティブ型のクラス

Ruby PHP
プリミティブ型は クラス ただの型
文字列への変換 to_s "{$変数}"
数値への変換 to_i intval()

RubyではString, Integer, Arrayといったプリミティブ型も全てがオブジェクトです。
一方、PHPにはプリミティブ型においてはクラスの概念はありません。

PHPではstringへの変換は、ダブルクウォートで囲った上で変数展開することによって実現します。
また、intに変換するにはintval()を使います。

objects/class.rb
int3 = 3

string3 = int3.to_s
p string3
# "3"

p string3.class
# String

re_int3 = string3.to_i
p re_int3
# 3

p re_int3.class
# Integer
objects/method.php
<?php
$int3 = 3;

$string3 = "{$int3}";
var_dump($string3);
// string(1) "3"

get_class($string3);
// Warning: get_class() expects parameter 1 to be object, string given in ...

$re_int3 = intval($string3);
var_dump($re_int3);
// int(3)

get_class($re_int3);
// Warning: get_class() expects parameter 1 to be object, int given in ...

値・オブジェクトに対する基本的な操作・変換

Ruby PHP
基本的な操作・変換は オブジェクトメソッド 標準関数の引数に渡す
文字数を調べる length / size mb_strlen()
配列を合計する sum array_sum()

Rubyでは値・オブジェクトに対する基本的な操作・変換はオブジェクトメソッドで実現します。
参考: class Object(Ruby 2.7.0 リファレンスマニュアル)

一方、PHPは標準関数が充実しており、その標準関数の引数として対象を渡すのが一般的です。

objects/method.rb
address = '千代田区千代田1-1'
puts address.length
# 10

fibonacci_numbers = [1, 1, 2, 3, 5, 8, 13]
puts fibonacci_numbers.sum
# 33
objects/method.php
<?php
$address = '千代田区千代田1-1';
echo mb_strlen($address);
// 10

$fibonacci_numbers = [1, 1, 2, 3, 5, 8, 13];
echo array_sum($fibonacci_numbers);
// 33

配列・ハッシュと、連想配列

Ruby PHP
配列の概念 配列 連想配列
連想配列の概念 ハッシュ 連想配列
配列の要素の取得 配列[インデックス] 連想配列[インデックス]
連想配列の要素の取得 配列[シンボル] 連想配列[キー]

Rubyでは配列と連想配列(ハッシュ)を使い分けます。
一方で、PHPはちょっと特殊で、連想配列しかありません。PHPにおける(連想配列でない)配列は、キーが数値である連想配列です。
また、Rubyでは連想配列のキーにはシンボルを使うことが多いと思いますが、PHPでは文字列をキーとすることが多いです。

objects/array.rb
days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
p days_of_week
# ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]

puts days_of_week[0]
# Monday

fruits = {red: 'apple', purple: 'grape', yellow: 'lemon'}
p fruits
# {:red=>"apple", :purple=>"grape", :yellow=>"lemon"}

puts fruits[:red]
# apple
objects/array.php
<?php
$days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
var_dump($days_of_week);
// array(7) {
//   [0]=>
//   string(6) "Monday"
//   [1]=>
//   string(7) "Tuesday"
//   [2]=>
//   string(9) "Wednesday"
//   [3]=>
//   string(8) "Thursday"
//   [4]=>
//   string(6) "Friday"
//   [5]=>
//   string(8) "Saturday"
//   [6]=>
//   string(6) "Sunday"
// }

echo $days_of_week[0];
// Monday

$fruits = ['red' => 'apple', 'purple' => 'grape', 'yellow' => 'lemon'];
var_dump($fruits);
// array(3) {
//   ["red"]=>
//   string(5) "apple"
//   ["purple"]=>
//   string(5) "grape"
//   ["yellow"]=>
//   string(5) "lemon"
//}

echo $fruits['red'];
// apple

配列への操作

Ruby PHP
配列への追加 配列 << 新要素 配列[] = 新要素
連想配列への追加 配列[シンボル] = 新要素 配列[キー] = 新要素
繰り返し処理 each foreach
繰り返し処理(返り値使用) map array_map()
繰り返し処理内での行いたい処理 ブロック コールバック関数

配列への追加は、Rubyは<<によってできる一方、PHPでは配列[] = 新要素という書き方を使います。
連想配列への追加は、書き方的にほぼ違いは無いかと思います。

手続き的な繰り返し処理は、Rubyならeach, PHPならforeachです。
返り値を使用したいときはRubyならmap, PHPならarray_map()を使います。

繰り返し処理中に行いたい処理を表現するのは、Rubyならブロック、PHPならコールバック関数を使います。
array_map()はよく使う割にはちょっと複雑な見た目をしていますね。

objects/array_function.rb
sequence_numbers = [1, 2, 3, 4, 5]
sequence_numbers << 6
p sequence_numbers
# [1, 2, 3, 4, 5, 6]

fruits = {red: 'apple', purple: 'grape', yellow: 'lemon'}
fruits[:orange] = 'pumpkin'
p fruits
# {:red=>"apple", :purple=>"grape", :yellow=>"lemon", :orange=>"pumpkin"}

sequence_numbers.each do |number|
  multiple_of_3 = number * 3
  puts multiple_of_3
end
# 3
# 6
# 9
# 12
# 15
# 18

multiples = sequence_numbers.map do |number|
  number * 3
end
p multiples
# [3, 6, 9, 12, 15, 18]
objects/array_function.php
<?php
$sequence_numbers = [1, 2, 3, 4, 5];
$sequence_numbers[] = 6;
var_dump($sequence_numbers);
// array(6) {
//   [0]=>
//   int(1)
//   [1]=>
//   int(2)
//   [2]=>
//   int(3)
//   [3]=>
//   int(4)
//   [4]=>
//   int(5)
//   [5]=>
//   int(6)
// }

$fruits = ['red' => 'apple', 'purple' => 'grape', 'yellow' => 'lemon'];
$fruits['orange'] = 'pumpkin';
var_dump($fruits);
// array(4) {
//   ["red"]=>
//   string(5) "apple"
//   ["purple"]=>
//   string(5) "grape"
//   ["yellow"]=>
//   string(5) "lemon"
//   ["orange"]=>
//   string(7) "pumpkin"
// }

foreach ($sequence_numbers as $number) {
    $multiple_of_3 = $number * 3;
    echo $multiple_of_3 . PHP_EOL;
}
// 3
// 6
// 9
// 12
// 15
// 18

$multiples = array_map(
    function ($number) {
        return $number * 3;
    },
    $sequence_numbers
);
var_dump($multiples);
// array(6) {
//   [0]=>
//   int(3)
//   [1]=>
//   int(6)
//   [2]=>
//   int(9)
//   [3]=>
//   int(12)
//   [4]=>
//   int(15)
//   [5]=>
//   int(18)
// }

クラス関連

クラスは重要なので、重点的に解説します。

インスタンス変数=プロパティ

Ruby PHP
メンバ変数 インスタンス変数 プロパティ
privateなメンバ変数の定義 不要 private $変数;
publicなメンバ変数の定義 @変数に代入し、attr_accessor public $変数;
コンストラクタ def initialize function __construct()
メンバ変数への代入 @変数に代入 $this->変数に代入
メンバ変数の呼び出し . ->

Rubyのインスタンス変数は、PHPのプロパティに該当します。
Rubyはインスタンス変数の宣言は特に必要なく、コンストラクタで@変数に代入してしまえば完了です。
一方、PHPだと宣言が必要で、private $変数;のように定義します。

また、メンバ変数を公開可能にしたいのであれば、Rubyではattr_accessorを使う一方、PHPではpublic $変数によって定義します。

classes/Person.rb
class Person
  attr_accessor :name

  def initialize name, age
    @name = name
    @age = age
  end
end

person = Person.new '一郎', 10
p person
# #<Person:0x00007ff39f158750 @name="一郎", @age=10>

puts person.name
# 一郎

puts person.age
# Traceback (most recent call last):
# classes/Person.rb:16:in `<main>': undefined method `age' for #<Person:0x00007ff39f158750 @name="一郎", @age=10> (NoMethodError)
classes/Person.php
<?PHP

class Person
{
    public $name;
    private $age;

    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age = $age;
    }
}

$person = new Person('一郎', 10);
var_dump($person);
// object(Person)#1 (2) {
//   ["name"]=>
//   string(6) "一郎"
//   ["age":"Person":private]=>
//   int(10)
// }

echo $person->name;
// 一郎

echo $person->age;
// Fatal error: Uncaught Error: Cannot access private property Person::$age in ...

クラスの定数

Ruby PHP
定数の定義 大文字 const 大文字
クラス外からの定数の呼び出し クラス::定数 クラス::定数
クラス内からの定数の呼び出し 定数 self::定数

PHPだと定数はconstを付けて宣言します。
クラス外からの呼び出しは、RubyでもPHPでも同じ書き方です。
PHPだとクラス内からの呼び出しではself::をつけます。

classes/Sample.rb
class Sample
  TEST_CODE = 'test_code'

  def print_code
    puts "コードは#{TEST_CODE}です。";
  end
end

puts Sample::TEST_CODE
# test_code

sample = Sample.new
sample.print_code
# コードはtest_codeです。
classes/Sample.php
<?PHP

class Sample
{
    const TEST_CODE = 'test_code';

    public function printCode()
    {
        $code = self::TEST_CODE;
        echo "コードは「{$code}」です。";
    }
}

echo Sample::TEST_CODE;
// test_code

$sample = new Sample();
$sample->printCode();
// コードは「test_code」です。

インスタンスメソッド

Ruby PHP
publicメソッドの定義方法 ただのdef public function()
privateメソッドの定義方法 privateの下でdef private function()

Rubyではクラス内で何も行わずにdefをするとpublicメソッドとなり、privateの下で定義されるとprivateメソッドになります。
一方、PHPではメソッドの定義時に必ずpublic/privateを定義します。
(本当はもっと色々種類がありますが割愛)

classes/Product.rb
class Product
    def initialize price, cost
        @price = price
        @cost = cost
    end

    def print_judgment
        if calc_profit > 0
            puts 'この商品は利益が出ます!どんどん売りましょう!';
        else
            puts 'この商品は利益が出ません...売るべきではないかもしれません...'
        end
    end

    private

    def calc_profit
        @price - @cost
    end
end

product = Product.new 120, 100
product.print_judgment
# この商品は利益が出ます!どんどん売りましょう!

product =  Product.new 90, 100
product.print_judgment
# この商品は利益が出ません...売るべきではないかもしれません...

product.calc_profit
# Traceback (most recent call last):
# classes/Product.rb:30:in `<main>': private method `calc_profit' called for #<Product:0x00007fc9f19dc408 @price=120, @cost=100> (NoMethodError)
classes/Product.php
<?php

class Product
{
    private $price;
    private $cost;

    public function __construct($price, $cost)
    {
        $this->price = $price;
        $this->cost = $cost;
    }

    public function printJudgment()
    {
        if ($this->calcProfit() > 0) {
            echo 'この商品は利益が出ます!どんどん売りましょう!';
        } else {
            echo 'この商品は利益が出ません...売るべきではないかもしれません...';
        }
    }

    private function calcProfit()
    {
        return $this->price - $this->cost;
    }
}

$product = new Product(120, 100);

$product->printJudgment();
// この商品は利益が出ます!どんどん売りましょう!

$product = new Product(90, 100);
$product->printJudgment();
// この商品は利益が出ません...売るべきではないかもしれません...

$product->calcProfit();
// Fatal error: Uncaught Error: Call to private method Product::calcProfit() from context '' in ...

クラスメソッドとstaticメソッド

Ruby PHP
静的メソッド クラスメソッド staticメソッド
インスタンスメソッド インスタンスメソッド staticでないメソッド
静的メソッドの定義方法 self static function()
静的メソッドの呼び出し クラス::メソッド クラス::メソッド

Rubyにおけるクラスメソッドは、PHPではstaticメソッドに該当します。
逆に、インスタンスメソッドはstaicでないメソッドということになります。

Rubyでクラスメソッドを定義するときは、class << selfの中で定義することが多いと思います。
一方で、PHPではメソッドの定義ごとにstaticを付与することで定義します。

また、public/privateはどんなメソッドでも付けるので、staticメソッドにもpublic/privateを付けて定義します。
静的メソッドの呼び出しの書き方は、RubyとPHPとでほぼ差は無いかと思います。

classes/VertebrateAnimal.rb
class VertebrateAnimal
  class << self
    def is_vertebrate_animal group
      get_vertebrate_animals.include? group
    end

    private

    def get_vertebrate_animals
      %w[fishes amphibians reptiles birds mammals]
    end
  end
end

is_vertebrate_animal1 = VertebrateAnimal::is_vertebrate_animal 'fishes'
puts is_vertebrate_animal1
# true

is_vertebrate_animal2 = VertebrateAnimal::is_vertebrate_animal 'insects'
puts is_vertebrate_animal2
# false
classes/VertebrateAnimal.php
<?PHP

class VertebrateAnimal
{
    public static function isVertebrateAnimal($group)
    {
        $vertebrate_animals = self::getVertebrateAnimals();
        return in_array($group, $vertebrate_animals, true);
    }

    private static function getVertebrateAnimals()
    {
        return ['fishes', 'amphibians', 'reptiles', 'birds', 'mammals'];
    }
}

$is_vertebrate_animal1 = VertebrateAnimal::isVertebrateAnimal('fishes');
var_dump($is_vertebrate_animal1);
// bool(true)

$is_vertebrate_animal2 = VertebrateAnimal::isVertebrateAnimal('insects');
var_dump($is_vertebrate_animal2);
// bool(false)

ゲッターとセッター

Ruby PHP
ゲッター attr_reader getXX()
セッター attr_writer setXX()

Rubyにおけるattr_readerおよびattr_writerに該当するような文法は、PHPにはありません。
よってgetXX, setXXという命名で自作することになります。

classes/Capsule.rb
class Capsule
  attr_reader :element
  attr_writer :element

  def initialize element
    @element = element
  end
end

capsule = Capsule.new '有効成分'
puts capsule.element
# 有効成分

p capsule
# #<Capsule:0x00007f8d909ac660 @element="有効成分">

capsule.element = '毒'
p capsule
# #<Capsule:0x00007f8d909ac660 @element="毒">
classes/Capsule.php
<?PHP

class Capsule
{
    private $element;

    public function __construct($element)
    {
        $this->element = $element;
    }

    public function getElement()
    {
        return $this->element;
    }

    public function setElement($element)
    {
        $this->element = $element;
    }
}

$capsule = new Capsule('有効成分');
echo $capsule->getElement();
// 有効成分

var_dump($capsule);
// object(Capsule)#1 (1) {
//   ["element":"Capsule":private]=>
//   string(12) "有効成分"
// }

$capsule->setElement('毒');
var_dump($capsule);
// object(Capsule)#1 (1) {
//   ["element":"Capsule":private]=>
//   string(3) "毒"
// }

その他ハマりポイント

ライブラリの対応関係

Ruby PHP
ライブラリ管理 Gem Composer
テスト Rspec PHPUnit
Linter Rubocop PHP-CS-Fixerなど
コメント RDoc PHPDoc
フレームワーク Ruby on Rails Laravel, CakePHPなど

有名どころのライブラリなどの対応関係のみを記載しました。
Rubyと言ったらRails、Railsと言ったらRubyという印象ですが、PHPではフレームワークは複数の選択肢があります。
シェアが高いという意味であればLaravelが近く、MVCの思想に忠実という意味ではCakePHPに近いかなという印象を持っています。

真偽判定・nil/null判定

Ruby PHP
== そこそこ使う 絶対に使わない
Null nil null
オブジェクトのNull確認 ! empty()

PHPの==はあまりにもヤバいことで有名だと思いますので、比較のときには必ず===を使うようにします。
Rubyでのnilは、PHPだとnullに該当します。

Rubyでは全てがオブジェクトであり、真偽値判定・nil判定がうまく設計されていて、オブジェクトのみで直感的に真偽値判定・nil判定をできることも多いです。
一方、PHPの場合は直感的に真偽値判定・null判定を行うのは危険なので、型を意識して判定した方が安全です。
オブジェクトがnullや空かどうかを確認するなら、empty()を使うのが有効です。

others/User.rb
class User
  class << self
    def find_by_id id
      # IDが1のときはユーザオブジェクトを返し、それ以外のときはユーザオブジェクトを返さないとします
      if id == 1
        User.new '最初のユーザ'
      else
        nil
      end
    end
  end

  def initialize name
    @name = name
  end
end

def print_user user
  # ユーザオブジェクトが存在するかを確認する
  if !user
    puts 'ユーザはいません'
  else
    p user
  end
end

user2 = User::find_by_id 2
print_user user2
# ユーザはいません

p user2
# nil

user1 = User::find_by_id 1
print_user user1
# #<User:0x00007fe70f173f88 @name="最初のユーザ">
others/User.php
<?php

class User
{
    private $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    static function findById($id)
    {
        /** IDが1のときはユーザオブジェクトを返し、それ以外のときはユーザオブジェクトを返さないとします */
        if ($id === 1) {
            return new static('最初のユーザ');
        } else {
            return null;
        }
    }
}

function printUser($user)
{
    // ユーザオブジェクトが存在するかを確認する
    if (empty($user)) {
        echo 'ユーザはいません';
    } else {
        var_dump($user);
    }
}

$user2 = User::findById(2);
printUser($user2);
// ユーザはいません

var_dump($user2);
// NULL

$user1 = User::findById(1);
printUser($user1);
// object(User)#1 (1) {
//   ["name":"User":private]=>
//   string(18) "最初のユーザ"
// }

if文の返り値

Ruby PHP
if文の返り値 最後の値 なし
分岐によって値を生成する場合 ifの返り値に入れる 一度値を初期化し、再代入する

PHPはif文の返り値が返ってきません。
そのため、分岐によって値を生成させるケースでは一度値を初期化するなどしてから再代入する、みたいな方法を取る必要があります。

どうしても再代入がいやだ、イミュータブルにしたい、という場合は三項演算子という方法もあります。
ただし、三項演算子は多くの場合は処理が分かりにくくなるだけなので、非推奨です。

others/day.rb
def print_ymd is_beginning_of_month
  today = Time.now

  datetime = if is_beginning_of_month
               Time.new today.year, today.month, 1 # is_beginning_of_month = falseでは現在日を返す
             else
               today # 月初を返す
             end

  puts datetime.strftime "%Y年%m月%d日です"
end

print_ymd false
# 2020年12月07日です

print_ymd true
# 2020年12月01日です
others/day.php
<?php

function printYmd($is_beginning_of_month)
{
    $today = new DateTimeImmutable();

    $datetime = null;
    if ($is_beginning_of_month) {
        // 月初を返す
        $datetime = new DateTimeImmutable($today->format('Y-m-01'));
    } else {
        // $is_beginning_of_month = falseでは現在日を返す
        $datetime = $today;
    }

    echo $datetime->format('Y年m月d日です');
}

printYmd(false);
// 2020年12月07日です

printYmd(true);
// 2020年12月01日です

/**
 * 別の書き方。コード量は少ないが分かりにくい
 */
function printYmd2($is_beginning_of_month)
{
    $today = new DateTimeImmutable();
    $datetime = $is_beginning_of_month ? new DateTimeImmutable($today->format('Y-m-01')) : $today;

    echo $datetime->format('Y年m月d日です');
}

名前付き引数がない(PHP7以前)

Ruby PHP7以前 PHP8以後
名前付き引数 引数名: なし 引数名:

PHP7以前では名前付き引数がありません。
よって、オプション引数と言いながらも順番を意識して代入する必要があります(辛い)。
このため、依存性注入が凄まじくやりづらいです。

PHP8には名前付き引数が導入されています。
【PHP8.0】PHPに名前付き引数が実装される

others/argument.rb
def calc_goku_scouter original_power, kaio_ken: 1, is_suppressed: false, is_super_saiyan: false
  power = original_power * kaio_ken

  if power > 5000 && is_suppressed
    power = 5000
  end

  if is_super_saiyan
    power += 100000000
  end

  power
end

puts calc_goku_scouter 85000
# 85000

puts calc_goku_scouter 85000, kaio_ken: 2
# 170000

puts calc_goku_scouter 85000, is_suppressed: true
# 5000

puts calc_goku_scouter 85000, kaio_ken: 20, is_super_saiyan: true
# 101700000
others/argument.php
<?php

function calcGokuScouter($original_power, $kaio_ken = 1, $is_suppressed = false, $is_super_saiyan = false)
{
    $power = $original_power * $kaio_ken;

    if ($power > 5000 && $is_suppressed) {
        $power = 5000;
    }

    if ($is_super_saiyan) {
        $power += 100000000;
    }

    return $power;
}

echo calcGokuScouter(85000);
// 85000

echo calcGokuScouter(85000, 2);
// 170000

echo calcGokuScouter(85000, 1, true);
// 5000

echo calcGokuScouter(85000, 20, false, true);
// 101700000

interfaceとabstract

Ruby PHP
インターフェース なし interface
抽象クラス なし abstract

Rubyには無い概念として、PHPにはinterface, abstractというものがあります。

特にinterfaceは重要なのですが、中々概念の理解が難しいかもしれません。
とても勉強になった記事があるので、貼っておきます。
脱PHP初心者!インターフェイスを理解しよう

abstractはGoFのデザインパターンでいうTemplate Methodパターンを実装するのに必要です。
参考になった記事を貼っておきます。
PHPによるデザインパターン入門 - TemplateMethod〜処理を穴埋めする - Do You PHP はてブロ

結び

いかがでしたか?
もし誤記・間違い・より良い書き方などあれば、ご指摘いただければと思います。
また他にこんなこと困ったよ!みたいなのもあれば、教えて頂けると嬉しいです。

一応GitHubにもコードをまとめておきました。
https://github.com/kumackey/php-ruby

他参考になりそうなもの

PHPer向けのRuby入門
この記事の逆パターンです。演習問題が付いてる優しさ。

PHPerがRubyを勉強するのに役に立つTips
同じくこの記事の逆パターン。

元PHPエンジニアがPHPとRubyを比較してみた
PHPとRubyの文法の違いなど。

PHPからRubyへ
Rubyの公式が出している、PHPとの違いというドキュメント

28
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?