Di PHP, kapan Anda menggunakannya
define('FOO', 1);
dan kapan Anda menggunakannya
const FOO = 1;
?
Apa perbedaan utama antara keduanya?
Di PHP, kapan Anda menggunakannya
define('FOO', 1);
dan kapan Anda menggunakannya
const FOO = 1;
?
Apa perbedaan utama antara keduanya?
Jawaban:
Pada PHP 5.3 ada dua cara untuk mendefinisikan konstanta : Entah menggunakan const
kata kunci atau menggunakan define()
fungsi:
const FOO = 'BAR';
define('FOO', 'BAR');
Perbedaan mendasar antara kedua cara tersebut adalah bahwa const
mendefinisikan konstanta pada waktu kompilasi, sedangkan define
mendefinisikannya pada saat run time. Ini menyebabkan sebagian besar const
kerugian. Beberapa kelemahan const
adalah:
const
tidak dapat digunakan untuk mendefinisikan konstanta secara kondisional. Untuk mendefinisikan konstanta global, ia harus digunakan dalam lingkup terluar:
if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}
Mengapa Anda tetap ingin melakukan itu? Satu aplikasi umum adalah untuk memeriksa apakah konstanta sudah ditentukan:
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const
menerima skalar statis (nomor, string atau konstan lain seperti true
, false
, null
, __FILE__
), sedangkan define()
mengambil ekspresi apapun. Karena PHP 5.6 ekspresi konstan juga diperbolehkan const
:
const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always valid
const
mengambil nama konstan polos, sedangkan define()
menerima ekspresi apa pun sebagai nama. Ini memungkinkan untuk melakukan hal-hal seperti ini:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
s selalu peka huruf besar kecil, sedangkan define()
memungkinkan Anda untuk mendefinisikan konstanta tidak peka huruf besar kecil dengan melewatkan true
sebagai argumen ketiga (Catatan: mendefinisikan konstanta peka-huruf tidak berlaku lagi pada PHP 7.3.0.):
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
Jadi, itulah sisi buruknya. Sekarang mari kita lihat alasan mengapa saya selalu menggunakan const
kecuali jika salah satu dari situasi di atas terjadi:
const
hanya membaca lebih baik. Ini adalah konstruksi bahasa alih-alih fungsi dan juga konsisten dengan cara Anda mendefinisikan konstanta di kelas.const
, sebagai konstruksi bahasa, dapat dianalisis secara statis dengan perkakas otomatis.const
mendefinisikan konstanta di namespace saat ini, sementara define()
harus melewati nama namespace lengkap:
namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');
Karena const
konstanta PHP 5.6 juga bisa berupa array, sementara define()
itu belum mendukung array. Namun, array akan didukung untuk kedua kasus di PHP 7.
const FOO = [1, 2, 3]; // Valid in PHP 5.6
define('FOO', [1, 2, 3]); // Invalid in PHP 5.6 and valid in PHP 7.0
Akhirnya, perhatikan bahwa const
juga dapat digunakan dalam kelas atau antarmuka untuk menentukan konstanta kelas atau antarmuka konstan. define
tidak dapat digunakan untuk tujuan ini:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Ringkasan
Kecuali jika Anda memerlukan jenis definisi kondisional atau ekspresi, gunakan const
s alih-alih define()
s - hanya demi keterbacaan!
const
konstruksi bahasa - lihat wiki.php.net/rfc/const_scalar_exprs
const
adalah kurangnya tanda kutip, artinya diformat sama dengan yang digunakan dalam IDE Anda.
define('a', $_GET['param']);
, const b = a;
bekerja dengan sempurna dan mendapatkan nilai saat const c = $_GET['param'];
tidak valid Apakah const
waktu kompilasi benar-benar? Saya kira tidak begitu ... (diuji pada PHP 7.0.7)
Hingga PHP 5.3, const
tidak bisa digunakan dalam lingkup global. Anda hanya bisa menggunakan ini dari dalam kelas. Ini harus digunakan ketika Anda ingin mengatur semacam opsi atau pengaturan konstan yang berkaitan dengan kelas itu. Atau mungkin Anda ingin membuat semacam enum.
define
dapat digunakan untuk tujuan yang sama, tetapi hanya dapat digunakan dalam lingkup global. Seharusnya hanya digunakan untuk pengaturan global yang mempengaruhi seluruh aplikasi.
Contoh const
penggunaan yang baik adalah untuk menghilangkan angka ajaib. Lihatlah konstanta PDO . Ketika Anda perlu menentukan jenis pengambilan, Anda akan mengetik PDO::FETCH_ASSOC
, misalnya. Jika const tidak digunakan, Anda akan mengetik sesuatu seperti 35
(atau apa pun FETCH_ASSOC
yang didefinisikan sebagai). Ini tidak masuk akal bagi pembaca.
Contoh define
penggunaan yang baik mungkin menentukan jalur akar aplikasi Anda atau nomor versi pustaka.
const
dengan ruang nama.
Saya tahu ini sudah dijawab, tetapi tidak ada jawaban saat ini yang menyebutkan namespacing dan bagaimana pengaruhnya terhadap konstanta dan definisi.
Pada PHP 5.3, konstanta dan definisi hampir sama dalam banyak hal. Namun, masih ada beberapa perbedaan penting:
const FOO = 4 * 3;
tidak bekerja, tetapi define('CONST', 4 * 3);
tidak. define
harus menyertakan namespace yang akan didefinisikan dalam namespace itu.Kode di bawah ini harus menggambarkan perbedaan.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
Konten dari sub-array pengguna akan ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== UPDATE ===
PHP 5.6 mendatang akan memungkinkan fleksibilitas yang lebih tinggi dengan const
. Anda sekarang dapat mendefinisikan const dalam hal ekspresi, asalkan ekspresi tersebut terdiri dari const lain atau literal. Ini berarti yang berikut ini harus valid pada 5.6:
const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // For future editors: THIS IS DELIBERATE! Read the answer comments below for more details
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;
Anda masih tidak akan dapat mendefinisikan const dalam hal variabel atau fungsi kembali, jadi
const RND = mt_rand();
const CONSTVAR = $var;
masih akan keluar.
FORTY_TWO
sebagai 54?
Saya percaya bahwa pada PHP 5.3, Anda dapat menggunakan di const
luar kelas, seperti yang ditunjukkan di sini dalam contoh kedua:
http://www.php.net/manual/en/language.constants.syntax.php
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
define
Saya gunakan untuk konstanta global.
const
Saya gunakan untuk konstanta kelas.
Anda tidak bisa define
masuk ke dalam ruang lingkup kelas, dan dengan const
Anda bisa. Tidak perlu dikatakan, Anda tidak dapat menggunakan const
ruang lingkup kelas luar.
Juga, dengan const
, itu benar-benar menjadi anggota kelas, dan dengan define
, itu akan didorong ke ruang lingkup global.
Jawaban NikiC adalah yang terbaik, tetapi izinkan saya menambahkan peringatan yang tidak jelas ketika menggunakan ruang nama sehingga Anda tidak terjebak dengan perilaku yang tidak terduga. Yang perlu diingat adalah bahwa definisi selalu di namespace global kecuali jika Anda secara eksplisit menambahkan namespace sebagai bagian dari pengidentifikasi define. Apa yang tidak jelas tentang itu adalah bahwa pengidentifikasi namespaced mengalahkan pengidentifikasi global. Jadi:
<?php
namespace foo
{
// Note: when referenced in this file or namespace, the const masks the defined version
// this may not be what you want/expect
const BAR = 'cheers';
define('BAR', 'wonka');
printf("What kind of bar is a %s bar?\n", BAR);
// To get to the define in the global namespace you need to explicitely reference it
printf("What kind of bar is a %s bar?\n", \BAR);
}
namespace foo2
{
// But now in another namespace (like in the default) the same syntax calls up the
// the defined version!
printf("Willy %s\n", BAR);
printf("three %s\n", \foo\BAR);
}
?>
menghasilkan:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
Yang bagi saya membuat seluruh gagasan const tidak perlu membingungkan karena ide tentang const dalam lusinan bahasa lain adalah bahwa itu selalu sama di mana pun Anda berada dalam kode Anda, dan PHP tidak benar-benar menjamin itu.
BAR
dan \foo\BAR
hanya tidak konstanta yang sama. Saya setuju itu benar-benar membingungkan, tetapi jika Anda juga menganggap hal-hal seperti logika namespacing konsisten dengan cara ini, dan tidak const
juga define()
tidak seperti makro C ( #define
), maka PHP dapat memiliki beberapa alasan.
Sebagian besar jawaban ini salah atau hanya menceritakan setengah dari cerita.
Sebagai contoh:
const AWESOME = 'Bob'; // Valid
Contoh buruk:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
Untuk membuat konstanta variabel, gunakan define () seperti:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
Ya, const didefinisikan pada waktu kompilasi dan karena status nikic tidak dapat diberikan ekspresi, seperti yang dapat didefinisikan () dapat. Tetapi juga const tidak dapat dinyatakan secara kondisional (untuk alasan yang sama). yaitu. Anda tidak dapat melakukan ini:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Sedangkan Anda bisa dengan define (). Jadi, itu tidak benar-benar turun ke preferensi pribadi, ada cara yang benar dan salah untuk menggunakan keduanya.
Sebagai tambahan ... Saya ingin melihat semacam konst kelas yang dapat diberi ekspresi, semacam define () yang dapat diisolasi ke kelas?
Untuk menambahkan jawaban NikiC. const
dapat digunakan di dalam kelas dengan cara berikut:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
Anda tidak dapat melakukan ini dengan define()
.
Tidak ada yang mengatakan apa-apa tentang php-doc, tetapi bagi saya itu juga argumen yang sangat signifikan untuk preferensi const
:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
Dengan menetapkan kata kunci konstan, Anda akan mendapatkan fasilitas case-insensitive tetapi dengan const kata kunci yang Anda tidak.
define("FOO", 1, true);
echo foo; //1
echo "<br/>";
echo FOO; //1
echo "<br/>";
class A {
const FOO = 1;
}
echo A::FOO; //valid
echo "<br/>";
//but
class B {
define FOO = 1; //syntax error, unexpected 'define'
}
echo B::FOO; //invalid
const
dua kali lebih cepat daripadadefine
. Tentang waktu buka halaman dan penggunaan memori: lihat pertanyaan ini dan artikel ini ... Lihat juga sesuatu tentang cache opcode di sini .