When a project needs the right technique, the question is usually simpler than the vocabulary suggests. Encoding changes representation. Hashing checks or fingerprints data. Encryption protects data so it can be recovered later with the right key.
Quick definitions
Encoding converts data into a different representation so it can move through a system or fit a format. It is reversible, but it does not hide meaning. Hashing turns input into a fixed-length digest that is designed for verification, not reversal. Encryption transforms readable data into ciphertext so it stays confidential until it is decrypted with the correct key.
That distinction matters. A Base64 string may look mysterious, but it is not a security boundary. Likewise, a hash can tell you whether content changed, but it cannot restore the original text. For a plain-language reference, PHP’s own manual pages on base64_encode(), password_hash(), and the OpenSSL encryption functions are a good anchor point.
The decision tree
Start with the outcome you need. The tool follows the job, not the other way around.
- Need a different representation for transport, URLs, or formatting? Use encoding.
- Need to verify that data has not changed? Use hashing.
- Need to keep a secret confidential? Use encryption.
- Need to store a password? Use password hashing, never encryption.
For secure passwords, the current PHP guidance is straightforward: use password_hash() and password_verify() rather than rolling your own scheme. The OWASP Password Storage Cheat Sheet is the other source I would keep open in a second tab.
Use cases and recommendations
URL-safe representation
When a string must survive a URL, query string, or form submission, encode it for that context. For example, urlencode() or rawurlencode() can make a parameter safe to place inside a URL. That is not protection from attackers; it is compatibility plumbing.
$value = 'search: PHP & security';
$query = 'q=' . rawurlencode($value);
// q=search%3A%20PHP%20%26%20security
If you are curious about the broader naming confusion, the Base64 overview on Wikipedia is useful precisely because it explains that the format is encoding, not secrecy.
Storing passwords
Password storage is where the separation between these terms becomes non-negotiable. A password should be hashed with a modern password API, with the library handling the salt and algorithm choice. Do not encrypt passwords so they can be “read back later.” If you can decrypt a password database, the design has already failed.
$hash = password_hash($plainPassword, PASSWORD_DEFAULT);
if (password_verify($attempt, $hash)) {
// credentials match
}
Verifying integrity
Hashes are useful when you want to detect changes. Common examples include checksums for downloads, signature-adjacent workflows, cache keys, and deduplication. If the same input must always produce the same fingerprint, a hash is the right family of tools.
For modern hashing guidance, the PHP hash() documentation is a better reference than any tutorial that still treats MD5 like a security solution. It is not one.
Protecting confidential values
If the data must remain secret but still needs to be recovered later, use encryption. Typical examples are API tokens stored for later use, customer notes that contain sensitive information, or configuration values that should not be visible in plain text.
A high-level AES-256 flow in PHP looks like this: generate or derive a key, create a unique IV for each encryption, encrypt the plaintext, store the ciphertext with the IV and any authentication tag, and keep the key in a protected secret store. Decryption reverses that process only when the key is available.
$cipher = 'aes-256-gcm';
$key = random_bytes(32); // example only; store keys outside the database
$iv = random_bytes(12);
$tag = '';
$ciphertext = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
$recovered = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv, $tag);
For the underlying mechanics, the PHP manual on openssl_decrypt() and the OpenSSL command-line documentation both help clarify what the algorithm does and does not guarantee.
Common mistakes to avoid
- Encrypting passwords instead of hashing them.
- Using MD5 or SHA-1 as if they were secure password storage.
- Using Base64 as if it were protection.
- Using AES when you only needed encoding.
- Reusing IVs or keys carelessly, which weakens encryption even when the algorithm is strong.
A practical memory aid
| Need | Use | Reason |
|---|---|---|
| Display or transport formatting | Encoding | Make data fit a channel or syntax |
| Integrity checking | Hashing | Detect changes without reversing the data |
| Password storage | Hashing with modern password functions | One-way by design, with salt and algorithm handling |
| Confidential storage | Encryption | Recover the original only with the right key |
Where to go next
If you are building a broader PHP security workflow, start with the site’s support page for contact and guidance, then review the blog index for adjacent practical notes. For implementation details, the best next step is not more vocabulary; it is matching the right primitive to the right problem.
That is the useful takeaway. The question is not “which one is strongest?” It is “what kind of problem am I solving?” Once you answer that, the choice is usually obvious.