PHP 与 Ruby 控制结构和函数的对比
1. 控制结构对比
在编程中,控制结构是实现程序逻辑的重要部分。PHP 和 Ruby 在控制结构上有相似之处,但也存在一些显著的差异。
1.1 if 语句
-
PHP
:使用
if和{}来定义条件语句,括号围绕被评估的表达式是必需的。
$value = 10;
if ($value > 5) {
print "value is \n";
print "greater than 5\n";
}
-
Ruby
:使用
if/end语法,括号围绕被评估的表达式是可选的。
value = 10
if value > 5
puts 'value is '
puts 'greater than 5'
end
还可以使用
if
和
unless
语句修饰符来编写单行条件语句。
$value = 10;
if ($value > 5)
print "value is greater than 5\n";
if (! $value > 5)
print "value is NOT greater than 5\n";
value = 10
puts 'value is greater than 5' if value > 5
puts 'value is NOT greater than 5' unless value > 5
1.2 else 和 elseif/elsif
-
else
:在 Ruby 中使用
else与 PHP 类似,三元运算符在两种语言中的工作方式相同。
$value = 10;
if ($value > 5) {
print 'value is greater than 5';
} else {
print 'value is NOT greater than 5';
}
$color = $value == 1 ? 'red' : 'blue';
value = 10
if value > 5
puts 'value is greater than 5'
else
puts 'value is NOT greater than 5'
end
color = value == 1 ? 'red' : 'blue'
-
elseif/elsif
:PHP 的
elseif关键字在 Ruby 中变为elsif。在 Ruby 中,如果想将语句与条件表达式放在同一行,可以使用冒号:或then关键字。
$value = 7;
if ($value > 8) {
print 'value is greater than 8';
} elseif ($value > 5) {
print 'value is greater than 5'
} else {
print 'value is NOT greater than 5';
}
value = 7
if value > 8
puts 'value is greater than 8'
elsif value > 5
puts 'value is greater than 5'
else
puts 'value is NOT greater than 5'
end
# variation using ":"
if value > 8:
puts 'value is greater than 8'
elsif value > 5: puts 'value is greater than 5'
else
puts 'value is NOT greater than 5'
end
# variation using "then"
if value > 8
then puts 'value is greater than 8'
elsif value > 5 then puts 'value is greater than 5'
else
puts 'value is NOT greater than 5'
end
1.3 循环结构
-
while 循环
:Ruby 使用
while/end风格的语法来定义while循环的开始和结束。
$page = 1;
while ($page < 5) {
print "$page\n";
$page++;
}
page = 1
while page < 5
puts page
page += 1
end
Ruby 还添加了
while
和
until
语句修饰符,以便可以在一行代码中编写简单的
while
语句。
$page = 1;
while ($page < 5)
$page++;
$page = 1;
while (! $page >= 5)
$page++;
page = 1
page += 1 while page < 5
page = 1
page += 1 until page >= 5
-
do while 循环
:Ruby 不支持
do/while,但有一个等效的语法,使用while或until语句修饰符在begin/end块表达式上。
$page = 1;
do {
print "$page\n";
$page++;
} while ($page < 10);
page = 1
begin
puts page
page += 1
end while page < 10
-
for 循环
:Ruby 在循环方面与 PHP 采取了不同的方法。Ruby 中没有
for结构,大多数循环方法利用整数对象上的迭代器方法。可以使用times或upto方法编写带有增量器的循环。
for ($i = 0; $i < 5; $i++) {
print "$i ";
}
5.times do |i|
print "#{i} "
end
0.upto(4) do |i|
print "#{i} "
end
可以使用
downto
方法创建带有减量器的循环。
for ($i = 4; $i >= 0; $i--) {
print "$i ";
}
4.downto(0) do |i|
print "#{i} "
end
要创建增量或减量时的间隔不是 1 的循环,可以使用 Ruby 的
step
方法。
for ($i = 0; $i < 5; $i += 2) {
print "$i ";
}
0.step(5, 2) do |i|
print "#{i} "
end
-
foreach 循环
:在 Ruby 中,数组的
foreach结构可以通过两种迭代器方法之一来完成。只需要遍历数组中的值时使用each方法。
$colors = array('blue', 'orange', 'red');
foreach ($colors as $color) {
print "$color ";
}
colors = ['blue', 'orange', 'red']
colors.each do |color|
print "#{color} "
end
当还需要数组的数字索引时,可以使用
each_with_index
方法。
foreach ($colors as $key => $color) {
print "$key=$color ";
}
colors.each_with_index do |color, i|
print "#{i}=#{color} "
end
当在哈希上使用
each
方法时,它将当前元素的键和值都传递给块。
$person = array('name' => 'Joe', 'eyes' => 'blue');
foreach ($person as $key => $value) {
print "$key=$value ";
}
person = {:name => 'Joe', :eyes => 'blue'}
person.each do |key, value|
print "#{key}=#{value} "
end
1.4 其他控制结构
-
break 语句
:在 PHP 和 Ruby 中,使用
break语句停止执行,但break的参数在两种语言中的工作方式不同。PHP 使用参数来确定要跳出多少个封闭语句,而 Ruby 将其视为语句的返回值。
$i = 0;
while (true) {
if ($i == 5) break;
print "$i ";
$i++;
}
$i = 1;
while ($i < 100) {
while ($i < 10) {
if ($i == 5) break 2;
$i++;
}
$i++;
}
print $i;
i = 0
while true
break if i == 5
puts "#{i} "
i += 1
end
i = 1
result = while i < 100
break "test" if i == 5
i += 1
end
puts result
-
continue/next 语句
:PHP 的
continue关键字在 Ruby 中被next取代。与 PHP 不同,Ruby 不允许使用额外的参数来指定跳过多少个循环。
$i = 0;
while ($i <= 10) {
$i++;
if ($i%2 == 1) continue;
print "$i ";
}
i = 0
while i <= 10
i += 1
next if i%2 == 1
puts "#{i} "
end
-
switch 语句
:Ruby 实现了
case表达式来替代 PHP 的switch。case表达式一旦找到匹配的值就不会继续评估语句,因此不需要break语句来停止执行。
switch (1) {
case 0:
print "equals 0\n";
case 1:
print "equals 1\n";
case 2:
print "equals 2\n";
}
$color = 'blue';
switch ($color) {
case 'red':
case 'yellow':
$type = "Warm";
break;
case 'blue':
case 'green':
$type = "Cool";
break;
default:
$type = "Invalid";
}
print "$type color\n";
case 1
when 0: puts "equals 0"
when 1: puts "equals 1"
when 2: puts "equals 2"
end
color = 'blue'
case color
when 'red', 'yellow':
type = "Warm"
when 'blue', 'green':
type = "Cool"
else
type = "Invalid"
end
puts "#{type} color"
type = case color
when 'red', 'yellow': "Warm"
when 'blue', 'green': "Cool"
else
"Invalid"
end
puts "#{type} color"
1.5 require 和 include
-
PHP
:
require_once用于加载外部文件一次,require可以多次加载。
require_once 'lib/sample_file.php';
require_once 'lib/sample_file.php';
require 'lib/sample_file.php';
require 'lib/sample_file.php';
-
Ruby
:
require方法与 PHP 的require_once类似,加载外部文件一次,.rb扩展名是可选的。load方法可以多次加载外部文件,需要指定文件扩展名。
require 'lib/sample_file'
require 'lib/sample_file'
load 'lib/sample_file.rb'
load 'lib/sample_file.rb'
2. 高级结构 - 块和函数
除了基本的控制结构,PHP 和 Ruby 在高级结构上也有不同的特点。
2.1 块(Blocks)
块是 Ruby 中特有的功能,用于将一段代码封装并传递给方法。可以使用花括号
{}
或
do/end
风格的语法来传递块。
# 单行块
['a', 'b', 'c'].each {|letter| puts letter }
# 多行块
['a', 'b', 'c'].each do |letter|
puts letter
puts letter.upcase
end
块的一个实际用途是执行事务操作。使用
yield
关键字来执行传递进来的块。
def dinner
puts "prepare meal"
yield
puts "wash dishes"
end
dinner { puts "eat lasagna" }
还可以向
yield
关键字传递参数,这些参数将被传递到块中使用。
def variations(name)
yield("upcase", name.upcase)
yield("downcase", name.downcase)
yield("capitalize", name.capitalize)
end
variations('joe') {|name, value| puts "#{name} = #{value}" }
可以通过调用
block_given?
来检查是否有块传递给方法。
def my_method
if block_given?
puts "block passed in"
else
puts "no block"
end
end
my_method
my_method {}
也可以将代码块传递给方法并使用
call
直接在方法中执行。
def my_method(arg1, &arg2)
arg2.call('block argument')
end
my_method('test') {|arg1| puts "Some data with #{arg1}" }
2.2 函数(Functions)
在 Ruby 中,实际上没有像 PHP 那样的函数概念。在 Ruby 中,每个函数实际上是定义在类或对象上的方法。任何在全局作用域中定义的方法实际上是
Object
类的方法。
def my_global_method
puts "I'm available everywhere!"
end
o = Object.new
o.my_global_method
class Car; end
c = Car.new
c.my_global_method
定义和调用方法在 Ruby 中不需要使用括号,当方法没有参数时,括号通常会被省略。
def drink_water
puts "Gulp, Gulp"
end
drink_water
def drink_beverage(type, size)
puts "Gulping down #{size} of #{type}"
end
drink_beverage "Gatorade", "gallon jug"
drink_beverage("Gatorade", "gallon jug")
用户定义的方法使用
def/end
语法,与 PHP 的
{}
不同。Ruby 中的方法名是区分大小写的。
function myFunction($arg1, $arg2, $arg3) {
return "return value \n";
}
print myFunction('a', 'b', 'c');
print mYfunCtion('a', 'b', 'c');
def my_function(arg1, arg2, arg3)
"return value"
end
puts my_function('a', 'b', 'c')
puts mY_funCtion('a', 'b', 'c')
Ruby 方法名可以以问号
?
、感叹号
!
或等号
=
结尾。问号通常用于返回布尔值的方法,等号用于作为左值属性赋值的方法,感叹号通常表示该方法会对接收对象进行破坏性操作。
class User
def admin=(admin)
@admin = admin
end
def admin?
@admin || false
end
end
joe = User.new
joe.admin = true
puts joe.admin?
foo = [2, 1, 3]
p foo.sort
p foo
p foo.sort!
p foo
Ruby 允许嵌套方法,与 PHP 中的嵌套函数类似,它们在外部方法执行之前是不可调用的。
function myFunction() {
function myInnerFunction() {
print "inner value\n";
}
}
myFunction();
myInnerFunction();
def my_function
def my_inner_function
print "inner value"
end
end
my_function
my_inner_function
2.3 函数参数
- 默认值 :与 PHP 类似,可以通过在方法定义中为参数赋值来使用默认值。但 Ruby 可以将任何数据类型作为默认值,而 PHP 不能将新对象作为默认值。
function myFunction($arg1='default', $arg2=array('a', 'b')) {
print "$arg1 $arg2[0]\n";
}
myFunction();
def my_function(arg1='default', arg2=['a', 'b'], arg3=Object.new)
puts "#{arg1} #{arg2[0]}"
end
my_function
- 哈希参数 :哈希可以在不使用花括号的情况下传递给方法,这种语法模拟了命名参数,在 Rails 中经常使用以提高代码的可读性。
def format(text, options = {})
text.reverse! if options[:reverse]
text.upcase! if options[:upcase]
text
end
puts format('Live not on evil.', :reverse => true, :upcase => true)
-
块参数
:可以使用单行花括号块或多行
do/end风格的块将可选块传递给方法。在方法定义中使用&前缀的最终参数来引用块。
def checker(value, &block)
value << block.call if block
value
end
puts checker('test')
puts checker('test') { " with a block" }
-
可变参数
:Ruby 有一个很好的处理可变参数的方法,使用
*前缀的数组参数来收集所有剩余的元素。
function myFunction() {
$argNum = func_num_args();
$args = func_get_args();
$first = array_shift($args);
$second = array_shift($args);
print "($argNum) total, first: $first\n";
}
myFunction('red', 'green', 'blue');
def my_function(*args)
arg_num = args.size
first = args.shift
second = args.shift
puts "(#{arg_num}) total, first: #{first}"
end
my_function('red', 'green', 'blue')
还可以要求指定数量的参数,并使用
*
运算符收集其余的参数。
function anotherFunction($first, $second) {
$args = func_get_args();
$third = $args[2];
print "first: $first, third: $third\n";
}
anotherFunction('red', 'green', 'blue');
def another_function(first, second, *more)
third = more.first
puts "first: #{first}, third: #{third}"
end
another_function('red', 'green', 'blue')
2.4 返回值
与 PHP 一样,Ruby 使用
return
关键字从方法返回值。但与 PHP 不同的是,Ruby 会隐式返回任何方法中最后一个被评估的表达式。通常在不需要时不使用
return
关键字是 Ruby 的常见约定。
function sayHi($name) {
return "hello, $name\n";
}
print sayHi('Joe');
def say_hi(name)
"hello, #{name}"
end
puts say_hi('Joe')
可以从方法返回任何值,并且通常返回一个数组,然后将其拆分为多个变量。Ruby 不需要使用
list
等函数来分配变量,可以简单地使用逗号分隔的名称列表。
function myColors() {
return array('red', 'green', 'blue');
}
list($color1, $color2, $color3) = myColors();
print "$color1\n";
def my_colors
%w{red green blue}
end
color1, color2, color3 = my_colors
puts color1
2.5 可变函数
存储方法名的变量可以像在 PHP 中一样用于调用该方法。在 Ruby 中,我们将方法名和参数数组传递给
send
方法来调用它。
function myFunction($arg1) {
print "$arg1 in my function!\n";
}
$a = 'myFunction';
$a('value');
def my_method(arg1)
puts "#{arg1} in my method!"
end
a = "my_method"
send(a, ["value"])
2.6 内置函数
PHP 有广泛的内置函数,都存在于全局作用域中,而 Ruby 采取了不同的方法。Ruby 方法围绕它们修改的对象构建,这意味着我们处理的每个数据类型都有其自己的方法。
$colors = array('blue', 'red');
$reversed = array_reverse($colors);
var_export($reversed);
colors = [:blue, :red]
reversed = colors.reverse
p reversed
这种差异很重要,因为它允许我们将功能从全局命名空间中逻辑分离,使得记忆函数更加容易,因为不需要使用任意前缀来分组相关函数。
通过对 PHP 和 Ruby 的控制结构和函数的对比,我们可以看到两种语言在实现相同功能时的不同方式。开发者可以根据项目的需求和个人的编程习惯来选择使用哪种语言。
PHP 与 Ruby 控制结构和函数的对比
3. 总结与对比表格
为了更清晰地展示 PHP 和 Ruby 在控制结构和函数方面的差异,下面通过表格进行总结:
| 类别 | PHP | Ruby |
| — | — | — |
|
if 语句
| 使用
if
和
{}
,括号围绕表达式必需 | 使用
if/end
,括号可选,有
if
和
unless
修饰符用于单行条件 |
|
else 和 elseif/elsif
|
else
和
elseif
常规使用 |
else
类似,
elseif
变为
elsif
,可使用
:
或
then
放同一行 |
|
while 循环
| 常规
while
语法 |
while/end
风格,有
while
和
until
修饰符用于单行循环 |
|
do while 循环
| 支持
do/while
| 无
do/while
,用
begin/end
结合
while
或
until
替代 |
|
for 循环
| 有
for
结构 | 无
for
,用
times
、
upto
、
downto
、
step
等迭代器方法 |
|
foreach 循环
|
foreach
遍历数组或关联数组 | 用
each
、
each_with_index
遍历数组,
each
遍历哈希 |
|
break 语句
| 参数确定跳出封闭语句数量 | 参数作为语句返回值 |
|
continue/next 语句
|
continue
可带参数指定跳过循环数 |
next
无额外参数指定跳过循环功能 |
|
switch 语句
|
switch
需
break
停止执行 |
case
表达式找到匹配值后自动停止,无需
break
|
|
require 和 include
|
require_once
加载一次,
require
可多次加载 |
require
类似
require_once
,
.rb
扩展名可选;
load
可多次加载,需扩展名 |
|
块(Blocks)
| 无 | 可使用
{}
或
do/end
传递代码块,用
yield
执行,可检查块是否传递 |
|
函数定义
| 使用
function
和
{}
| 使用
def/end
,方法名区分大小写 |
|
函数参数
| 可设默认值,不能将新对象作默认值 | 可设默认值,任何数据类型可作默认值,有哈希参数、块参数、可变参数处理方式 |
|
返回值
| 用
return
返回值 | 用
return
返回值,也会隐式返回最后表达式,常不使用
return
|
|
可变函数
| 变量存储函数名直接调用 | 变量存储方法名,用
send
方法调用 |
|
内置函数
| 大量内置函数在全局作用域 | 方法围绕对象构建,各数据类型有自己方法 |
4. 流程图展示
下面通过 mermaid 流程图展示 Ruby 中一个常见的循环操作流程,以
times
方法为例:
graph TD;
A[开始] --> B[定义循环次数 n];
B --> C[初始化计数器 i = 0];
C --> D{i < n};
D -- 是 --> E[执行块内代码];
E --> F[i = i + 1];
F --> D;
D -- 否 --> G[结束];
这个流程图展示了 Ruby 中
n.times do |i| ... end
循环的执行过程。首先定义循环次数
n
,然后初始化计数器
i
为 0,每次循环检查
i
是否小于
n
,如果是则执行块内代码并将
i
加 1,直到
i
不小于
n
时结束循环。
5. 实际应用建议
在实际开发中,选择 PHP 还是 Ruby 可以根据以下因素考虑:
-
项目类型
:
- 如果是 Web 开发,尤其是快速搭建网站和应用,PHP 有丰富的 Web 开发框架如 Laravel、CodeIgniter 等,社区资源丰富,开发效率高。
- 如果是开发复杂的 Web 应用、微服务或者对代码简洁性和灵活性要求较高,Ruby on Rails 是一个很好的选择,它遵循“约定优于配置”的原则,能快速开发出高质量的应用。
-
团队技术栈
:如果团队成员对 PHP 比较熟悉,那么使用 PHP 进行开发可以减少学习成本,提高开发效率。反之,如果团队有 Ruby 开发经验,Ruby 可能更合适。
-
性能要求
:PHP 在性能上有一定优势,尤其是在处理高并发和大规模数据时。而 Ruby 在性能方面相对较弱,但通过一些优化手段和工具也能满足大多数应用的需求。
6. 总结
通过对 PHP 和 Ruby 的控制结构和函数的详细对比,我们深入了解了这两种语言在实现相同功能时的不同方式。PHP 具有广泛的内置函数和成熟的 Web 开发生态,适合快速开发和处理大规模数据。Ruby 则以其简洁、灵活的语法和强大的块功能,在构建复杂应用和提高开发效率方面表现出色,尤其是 Ruby on Rails 框架的使用。
开发者在选择使用哪种语言时,应综合考虑项目需求、团队技术栈、性能要求等因素,充分发挥每种语言的优势,以实现最佳的开发效果。同时,了解两种语言的差异也有助于开发者在不同的项目场景中灵活切换和运用。
超级会员免费看
173万+

被折叠的 条评论
为什么被折叠?



