Anda di halaman 1dari 193

1 Notas para Profissionais Notas PHP para Profissionais

2
3 aviso Legal
4 Este é um livro gratuito não oficial criado para fins educacionais e é
5 não é compatível com o (s) grupo (s) de PHP o.cial ou empresa (s)
6 Todas as marcas comerciais e marcas registradas são
7 a propriedade de seus respectivos proprietários
8 Mais de 400 páginas
9 de dicas e truques profissionais
10 FF
11 Conteúdo
12 Sobre 1
13 Capítulo 1: Introdução ao PHP 2
14 Seção 1.1: saída HTML do servidor da web 2
15 Seção 1.2: Olá, mundo! 3
16 Seção 1.3: Saída não HTML do servidor da web 3
17 Seção 1.4: Servidor embutido no PHP 5
18 Seção 1.5: CLI do PHP 5
19 Seção 1.6: Separação de Instrução 6
20 Seção 1.7: Tags PHP 7
21 Capítulo 2: Variáveis 9
22 Seção 2.1: Acessando uma variável dinamicamente por nome (variáveis variáveis) 9
23 Seção 2.2: Tipos de Dados 10
24 Seção 2.3: Melhores práticas de variáveis globais 13
25 Seção 2.4: Valores padrão de variáveis não inicializadas 14
26 Seção 2.5: Veracidade do Valor Variável e Operador Idêntico 15
27 Capítulo 3: Escopo Variável 18
28 Seção 3.1: Variáveis superglobais 18
29 Seção 3.2: Propriedades estáticas e variáveis 18
30 Seção 3.3: Variáveis globais definidas pelo usuário 19
31 Capítulo 4: Variáveis Superglobais PHP 21
32 Seção 4.1: Subesferas explicadas 21
33 Seção 4.2: PHP5 SuperGlobals 28
34 Capítulo 5: Saída do Valor de uma Variável 32
35 Seção 5.1: eco e impressão 32
36 Seção 5.2: Gerando uma visão estruturada de matrizes e objetos 33
37 Seção 5.3: Concatenação de strings com eco 35
38 Seção 5.4: printf vs sprintf 36
39 Seção 5.5: Gerando inteiros grandes 36
40 Seção 5.6: Saída de uma Matriz Multidimensional com índice e valor e impressão na
tabela 37
41 Capítulo 6: Constantes 39
42 Seção 6.1: Definindo constantes 39
43 Seção 6.2: Constantes de Classe 40
44 Seção 6.3: Verificando se a constante está definida 40
45 Seção 6.4: Usando constantes 42
46 Seção 6.5: Matrizes constantes 42
47 Capítulo 7: Constantes Mágicas 43
48 Seção 7.1: Diferença entre __FUNCTION__ e __METHOD__ 43
49 Seção 7.2: Diferença entre __CLASS__, get_class () e get_called_class () 43
50 Seção 7.3: Constantes de arquivos e diretórios 44
51 Capítulo 8: Comentários 45
52 Seção 8.1: Comentários de linha única 45
53 Seção 8.2: Comentários de múltiplas linhas 45
54 Capítulo 9: Tipos 46
55 Seção 9.1: Comparação de Tipos 46
56 Seção 9.2: Booleano 46
57 Seção 9.3: Flutuante 47
58 FF
59 Seção 9.4: Cordas 48
60 Seção 9.5: Chamada 50
61 Seção 9.6: Recursos 50
62 Seção 9.7: Fundição de Tipo 51
63 Seção 9.8: Tipo de malabarismo 51
64 Seção 9.9: Nulo 52
65 Seção 9.10: Inteiros 52
66 Capítulo 10: Operadores 54
67 Seção 10.1: Operador Coalescente Nulo (??) 54
68 Seção 10.2: Operador de Nave Espacial (<=>) 55
69 Seção 10.3: Operador de Execução (``) 55
70 Seção 10.4: Incrementando (++) e Decrementando Operadores () 55
71 Seção 10.5: Operador Ternário (? :) 56
72 Seção 10.6: Operadores lógicos (&& /AND e || /OR) 57
73 Seção 10.7: Operadores de String ( E =) 57
74 Seção 10.8: Objeto e Operadores de Classe 57
75 Seção 10.9: Atribuição Combinada (+ = etc) 59
76 Seção 10.10: Alterando a precedência do operador (com parênteses) 59
77 Seção 10.11: Atribuição básica (=) 60
78 Seção 10.12: Associação 60
79 Seção 10.13: Operadores de comparação 60
80 Seção 10.14: Operadores Bitabit 62
81 Seção 10.15: instanceof (type operator) 64
82 Capítulo 11: Referências 67
83 Seção 11.1: Atribuir por referência 67
84 Seção 11.2: Retorno por Referência 67
85 Seção 11.3: Passe por Referência 68
86 Capítulo 12: Matrizes 71
87 Seção 12.1: Inicializando um array 71
88 Seção 12.2: Verificar se a chave existe 73
89 Seção 12.3: Validando o tipo de array 74
90 Seção 12.4: Criando uma matriz de variáveis 74
91 Seção 12.5: Verificando se existe um valor no array 74
92 Seção 12.6: Interfaces ArrayAccess e Iterator 75
93 Capítulo 13: Array iteration 79
94 Seção 13.1: Iterando vários arrays juntos 79
95 Seção 13.2: Usando um índice incremental 80
96 Seção 13.3: Usando ponteiros de matriz interna 80
97 Seção 13.4: Usando o foreach 81
98 Seção 13.5: Usando o ArrayObject Iterator 83
99 Capítulo 14: Execução em um array 84
100 Seção 14.1: Aplicando uma função para cada elemento de um array 84
101 Seção 14.2: Dividir matriz em blocos 85
102 Seção 14.3: Implodindo um array em string 86
103 Seção 14.4: Matrizes "Destructuring" usando list () 86
104 Seção 14.5: array_reduce 86
105 Seção 14.6: Empurre um valor em um array 87
106 Capítulo 15: Manipulando uma Matriz 89
107 Seção 15.1: Filtrando uma matriz 89
108 Seção 15.2: Removendo elementos de uma matriz 90
109 FF
110 Seção 15.3: Classificando uma Matriz 91
111 Seção 15.4: Whitelist apenas algumas chaves de matriz 96
112 Seção 15.5: Adicionando elemento ao início do array 96
113 Seção 15.6: Valores de troca com chaves 97
114 Seção 15.7: Mesclar dois arrays em um array 97
115 Capítulo 16: Processando vários arrays juntos 99
116 Seção 16.1: Interseção da matriz 99
117 Seção 16.2: Mesclar ou concatenar matrizes 99
118 Seção 16.3: Mudando um array multidimensional para array associativo 100
119 Seção 16.4: Combinando dois arrays (chaves de um, valores de outro) 100
120 Capítulo 17: Classe de Data e Hora 102
121 Seção 17.1: Crie uma versão imutável do DateTime from Mutable antes do PHP 5.6 102
122 Seção 17.2: Adicionar ou Subtrair Intervalos de Data 102
123 Seção 17.3: getTimestamp 102
124 Seção 17.4: setDate 103
125 Seção 17.5: Crie o DateTime no formato personalizado 103
126 Seção 17.6: Imprimindo DateTimes 103
127 Capítulo 18: Trabalhando com Datas e Horário 105
128 Seção 18.1: Obtendo a diferença entre duas datas /horas 105
129 Seção 18.2: Converter uma data em outro formato 105
130 Seção 18.3: Analisar descrições de datas em inglês em um formato de data 107
131 Seção 18.4: Usando constantes predefinidas para o formato de data 107
132 Capítulo 19: Estruturas de Controle 109
133 Seção 19.1: se mais 109
134 Seção 19.2: Sintaxe alternativa para estruturas de controle 109
135 Seção 19.3: enquanto 109
136 Seção 19.4: dowhile 110
137 Seção 19.5: goto 110
138 Seção 19.6: declarar 110
139 Seção 19.7: incluir e requerer 111
140 Seção 19.8: retorno 112
141 Seção 19.9: para 112
142 Seção 19.10: foreach 113
143 Seção 19.11: if elseif else 113
144 Seção 19.12: se 114
145 Seção 19.13: switch 114
146 Capítulo 20: Loops 116
147 Seção 20.1: continuar 116
148 Seção 20.2: break 117
149 Seção 20.3: foreach 118
150 Seção 20.4: fazer .enquanto 118
151 Seção 20.5: para 119
152 Seção 21.1: Listas de argumentos de tamanho variável 121
153 Seção 21.2: Parâmetros Opcionais 122
154 Seção 21.3: Passando argumentos por referência 123
155 Seção 21.4: Uso Básico da Função 124
156 Seção 21.5: Escopo da Função 124
157 FF
158 Capítulo 22: Programação Funcional 125
159 Seção 22.1: Fechamentos 125
160 Seção 22.2: Atribuição às variáveis 126
161 Seção 22.3: Objetos como uma função 126
162 Seção 22.4: Usando variáveis externas 127
163 Seção 22.5: Função Anônima 127
164 Seção 22.6: Funções puras 128
165 Seção 22.7: Métodos funcionais comuns em PHP 128
166 Seção 22.8: Usando funções internas como retornos de chamada 129
167 Seção 22.9: Escopo 129
168 Seção 22.10: Passando uma função de retorno de chamada como um parâmetro 129
169 Capítulo 23: Sintaxe Alternativa para Estruturas de Controle 131
170 Seção 23.1: Instrução alternativa if /else 131
171 Seção 23.2: Alternativa para declaração 131
172 Seção 23.3: Alternativa enquanto declaração 131
173 Seção 23.4: Alternativa para a declaração 131
174 Seção 23.5: Instrução alternativa de troca 132
175 Capítulo 24: Formatação de String 133
176 Seção 24.1: Interpolação de strings 133
177 Seção 24.2: Extraindo /substituindo substrings 134
178 Capítulo 25: Análise de String 136
179 Seção 25.1: Divisão de uma string por separadores 136
180 Seção 25.2: Substring 136
181 Seção 25.3: Pesquisando uma substring com strpos 138
182 Seção 25.4: Cadeia de análise usando expressões regulares 139
183 Capítulo 26: Classes e Objetos 140
184 Seção 26.1: Constantes de Classe 140
185 Seção 26.2: Classes Abstratas 142
186 Seção 26.3: Enlace estático atrasado 144
187 Seção 26.4: Espaçamento de Nomes e Carregamento Automático 145
188 Seção 26.5: Método e Visibilidade da Propriedade 147
189 Seção 26.6: Interfaces 149
190 Seção 26.7: Palavrachave final 152
191 Seção 26.8: Carregamento automático 153
192 Seção 26.9: Chamando um construtor pai ao instanciar uma criança 154
193 Seção 26.10: Encadernação Dinâmica 155
194 Seção 26.11: $this, self e estático mais o singleton 156
195 Seção 26.12: Definindo uma Classe Básica 159
196 Seção 26.13: Classes Anônimas 160
197 Capítulo 27: Namespaces 162
198 Seção 27.1: Declarando namespaces 162
199 Seção 27.2: Referenciando uma classe ou função em um namespace 162
200 Seção 27.3: Declarando subnamespaces 163
201 Seção 27.4: O que são namespaces? 164
202 Capítulo 28: Sessões 165
203 Seção 28.1: session_start () Opções 165
204 Seção 28.2: Bloqueio de Sessão 165
205 Seção 28.3: Manipulando dados da sessão 166
206 Seção 28.4: Destruir uma sessão inteira 166
207 FF
208 Seção 28.5: Início da sessão segura sem erros 167
209 Seção 28.6: Nome da sessão 167
210 Capítulo 29: Cookies 169
211 Seção 29.1: Modificando um Cookie 169
212 Seção 29.2: Configurando um Cookie 169
213 Seção 29.3: Verificando se um cookie está definido 170
214 Seção 29.4: Removendo um Cookie 170
215 Seção 29.5: Recuperando um Cookie 170
216 Capítulo 30: Buffer de saída 171
217 Seção 30.1: Uso básico obtendo conteúdo entre bu.ers e clearing 171
218 Seção 30.2: Processando o buffer através de um retorno de chamada 171
219 Seção 30.3: Buffer de saída aninhada 172
220 Seção 30.4: Executando o buffer de saída antes de qualquer conteúdo 173
221 Seção 30.5: Saída de fluxo para o cliente 174
222 Seção 30.6: Usando o Buffer de Saída para armazenar o conteúdo de um arquivo, útil
para relatórios, faturas, etc 174
223 Seção 30.7: Uso típico e razões para usar ob_start 174
224 Seção 30.8: Capturando o bufer de saída para reutilizar mais tarde 175
225 Capítulo 31: JSON 177
226 Seção 31.1: Decodificando uma string JSON 177
227 Seção 31.2: Codificando uma string JSON 180
228 Seção 31.3: Depurando erros de JSON 183
229 Seção 31.4: Usando o JsonSerializable em um objeto 184
230 Seção 31.5: cabeçalho json e a resposta retornada 185
231 Capítulo 32: Cliente SOAP 187
232 Seção 32.1: Modo WSDL 187
233 Seção 32.2: Modo não WSDL 187
234 Seção 32.3: Classmaps 187
235 Seção 32.4: Solicitação e resposta SOAP de rastreamento 188
236 Capítulo 33: Usando o cURL no PHP 190
237 Seção 33.1: Uso básico (solicitações GET) 190
238 Seção 33.2: Solicitações do POST 190
239 Seção 33.3: Usando Cookies 191
240 Seção 33.4: Usando o multi_curl para fazer várias solicitações POST 192
241 Seção 33.5: Enviando dados multidimensionais e vários arquivos com o CurlFile em uma
solicitação
242 Seção 33.6: Criando e enviando uma solicitação com um método personalizado 196
243 Seção 33.7: Obter e definir cabeçalhos http personalizados no php 196
244 Capítulo 34: Reflexão 198
245 Seção 34.1: Detecção de recurso de classes ou objetos 198
246 Seção 34.2: Testando métodos privados /protegidos 198
247 Seção 34.3: Acessando variáveis de membros privados e protegidos 200
248 Capítulo 35: Injeção de Dependência 202
249 Seção 35.1: Injeção de Construtor 202
250 Seção 35.2: Injeção do Setter 202
251 Seção 35.3: Injeção de Contêineres 204
252 Capítulo 36: XML 205
253 Seção 36.1: Criar um XML usando o DomDocument 205
254 Seção 36.2: Ler um documento XML com o DOMDocument 206
255 Seção 36.3: Aproveitando o XML com a biblioteca SimpleXML do PHP 207
256 Seção 36.4: Criar um arquivo XML usando XMLWriter 209
257 FF
258 Seção 36.5: Ler um documento XML com SimpleXML 210
259 Capítulo 37: SimpleXML 212
260 Seção 37.1: Carregando dados XML em simplexml 212
261 Capítulo 38: Analisando HTML 213
262 Seção 38.1: Analisando HTML de uma string 213
263 Seção 38.2: Usando o XPath 213
264 Seção 38.3: SimpleXML 213
265 Capítulo 39: Expressões Regulares (regexp /PCRE) 215
266 Seção 39.1: Correspondência Global de RegExp 215
267 Seção 39.2: Correspondência de strings com expressões regulares 216
268 Seção 39.3: Dividir string em array por uma expressão regular 217
269 Seção 39.4: String substituindo com expressão regular 217
270 Seção 39.5: String substituir por retorno de chamada 217
271 Capítulo 40: Características 219
272 Seção 40.1: O que é uma característica? 219
273 Seção 40.2: Características para facilitar a reutilização de código horizontal 220
274 Seção 40.3: Resolução de Conflitos 221
275 Seção 40.4: Implementando um Singleton usando Características 222
276 Seção 40.5: Características para manter as classes limpas 223
277 Seção 40.6: Uso de Múltiplas Funções 224
278 Seção 40.7: Alterando a Visibilidade do Método 224
279 Capítulo 41: Gerenciador de Dependências do Composer 226
280 Seção 41.1: O que é o Composer? 226
281 Seção 41.2: Carregamento automático com o Composer 227
282 Seção 41.3: Diferença entre 'composer install' e 'composer update' 227
283 Seção 41.4: Comandos Disponíveis do Composer 228
284 Seção 41.5: Benefícios do uso do Composer 229
285 Seção 41.6: Instalação 230
286 Capítulo 42: Métodos Mágicos 231
287 Seção 42.1: __call () e __callStatic () 231
288 Seção 42.2: __get (), __set (), __isset () e __unset () 232
289 Seção 42.3: __construct () e __destruct () 233
290 Seção 42.4: __toString () 234
291 Seção 42.5: __clone () 235
292 Seção 42.6: __invoke () 235
293 Seção 42.7: __sleep () e __wakeup () 236
294 Seção 42.8: __debugInfo () 236
295 Capítulo 43: Manipulação de arquivos 238
296 Seção 43.1: Funções de conveniência 238
297 Seção 43.2: Excluindo arquivos e diretórios 240
298 Seção 43.3: Obtendo informações sobre o arquivo 240
299 Seção 43.4: arquivo baseado em fluxo IO 242
300 Seção 43.5: Movendo e copiando arquivos e diretórios 244
301 Seção 43.6: Minimize o uso da memória ao lidar com arquivos grandes 245
302 Capítulo 44: Fluxos 246
303 Seção 44.1: Registrando um wrapper de fluxo 246
304 Capítulo 45: Sugestão de Tipo 248
305 Seção 45.1: Classes e interfaces de dicas de tipos 248
306 Seção 45.2: Tipos escalares de dica de tipos, matrizes e callables 249
307 FF
308 Seção 45.3: Dicas do tipo anulável 250
309 Seção 45.4: Objetos genéricos de dicas de tipos 251
310 Seção 45.5: Tipo Sugestões Sem Devolução (Anular) 252
311 Capítulo 46: Filtros e Funções de Filtro 253
312 Seção 46.1: Validando valores booleanos 253
313 Seção 46.2: A validação de um número é um float 253
314 Seção 46.3: Validar um endereço MAC 254
315 Seção 46.4: Endereços de email da Sanitze 254
316 Seção 46.5: Higienizar inteiros 255
317 Seção 46.6: Sanitize URLs 255
318 Seção 46.7: Validar endereço de email 256
319 Seção 46.8: Validando um valor é um inteiro 256
320 Seção 46.9: Validando um Integer cai em um intervalo 257
321 Seção 46.10: validar uma URL 257
322 Seção 46.11: Sanitize Floats 259
323 Seção 46.12: Validar Endereços IP 261
324 Seção 46.13: Sanitize filters 262
325 Capítulo 47: Geradores 263
326 Seção 47.1: A palavrachave de rendimento 263
327 Seção 47.2: Lendo um arquivo grande com um gerador 264
328 Seção 47.3: Por que usar um gerador? 264
329 Seção 47.4: Usando a função send () para passar valores para um gerador 265
330 Capítulo 48: UTF8 267
331 Seção 48.1: Entrada 267
332 Seção 48.2: Saída 267
333 Seção 48.3: Armazenamento e Acesso de Dados 267
334 Capítulo 49: Suporte Unicode em PHP 269
335 Seção 49.1: Convertendo caracteres Unicode para o formato “\ uxxxx” usando PHP 269
336 Seção 49.2: Convertendo caracteres Unicode em seu valor numérico e /ou entidades
HTML usando PHP
337 269
338 Seção 49.3: Extensão internacional para suporte Unicode 271
339 Capítulo 50: URLs 272
340 Seção 50.1: Analisando uma URL 272
341 Seção 50.2: Construir uma string de consulta codificada por URL a partir de uma
matriz 272
342 Seção 50.3: redirecionando para outra URL 273
343 Capítulo 51: Como quebrar uma URL 275
344 Seção 51.1: Usando parse_url () 275
345 Seção 51.2: Usando o explode () 276
346 Seção 51.3: Usando o basename () 276
347 Capítulo 52: Serialização de Objetos 278
348 Seção 52.1: Serialize /Unserialize 278
349 Seção 52.2: A interface Serializável 278
350 Capítulo 53: Serialização 280
351 Seção 53.1: Serialização de tipos diferentes 280
352 Seção 53.2: Problemas de segurança com unserialize 281
353 Capítulo 54: Encerramento 284
354 Seção 54.1: Uso básico de um fechamento 284
355 Seção 54.2: Usando variáveis externas 284
356 Seção 54.3: Enlace de fechamento básico 285
357 FF
358 Seção 54.4: Ligação e escopo de fechamento 285
359 Seção 54.5: Ligando um fechamento para uma chamada 287
360 Seção 54.6: Use fechamentos para implementar o padrão de observação 287
361 Capítulo 55: Ler Dados da Solicitação 290
362 Seção 55.1: Lendo dados POST brutos 290
363 Seção 55.2: Lendo dados do POST 290
364 Seção 55.3: Lendo dados GET 290
365 Seção 55.4: Manipulando erros de upload de arquivos 291
366 Seção 55.5: Passando matrizes pelo POST 291
367 Seção 55.6: Carregando arquivos com HTTP PUT 293
368 Capítulo 56: Malabarismo de tipos e questões de comparação não estritas 294
369 Seção 56.1: O que é malabarismo de tipos? 294
370 Seção 56.2: Lendo de um arquivo 294
371 Seção 56.3: Trocar surpresas 295
372 Seção 56.4: Digitação estrita 296
373 Capítulo 57: Soquetes 298
374 Seção 57.1: Soquete do cliente TCP 298
375 Seção 57.2: soquete do servidor TCP 299
376 Seção 57.3: soquete do servidor UDP 299
377 Seção 57.4: Manipulando erros de socket 300
378 Capítulo 58: PDO 301
379 Seção 58.1: Prevenindo injeção SQL com consultas parametrizadas 301
380 Seção 58.2: Conexão e recuperação do PDO básico 302
381 Seção 58.3: Transações do banco de dados com o PDO 303
382 Seção 58.4: PDO: conectandose ao servidor MySQL /MariaDB 305
383 Seção 58.5: PDO: Obter número de linhas afetadas por uma consulta 306
384 Seção 58.6: PDO :: lastInsertId () 306
385 Capítulo 59: PHP MySQLi 308
386 Seção 59.1: Fechar conexão 308
387 Seção 59.2: conexão MySQLi 308
388 Seção 59.3: Loop através dos resultados do MySQLi 309
389 Seção 59.4: Instruções preparadas no MySQLi 309
390 Seção 59.5: Escape de Strings 310
391 Seção 59.6: Depurando SQL no MySQLi 311
392 Seção 59.7: consulta do MySQLi 311
393 Seção 59.8: Como obter dados de uma declaração preparada 312
394 Seção 59.9: ID de Inserção do MySQLi 314
395 Capítulo 60: SQLite3 316
396 Seção 60.1: Tutorial de início rápido do SQLite3 316
397 Seção 60.2: Consultando um banco de dados 317
398 Seção 60.3: Recuperando apenas um resultado 318
399 Capítulo 61: Usando o MongoDB 319
400 Seção 61.1: Conectar ao MongoDB 319
401 Seção 61.2: Obter vários documentos find () 319
402 Seção 61.3: Obter um documento findOne () 319
403 Seção 61.4: Inserir documento 319
404 Seção 61.5: Atualizar um documento 319
405 Seção 61.6: Excluir um documento 320
406 Capítulo 62: mongophp 321
407 FF
408 Seção 62.1: Tudo entre o MongoDB e o Php 321
409 Capítulo 63: Usando o Redis com PHP 324
410 Seção 63.1: Conectando a uma instância do Redis 324
411 Seção 63.2: Instalando o PHP Redis no Ubuntu 324
412 Seção 63.3: Executando comandos do Redis no PHP 324
413 Capítulo 64: Enviando email 325
414 Seção 64.1: Enviando email Noções básicas, mais detalhes e um exemplo completo 325
415 Seção 64.2: Enviando email em HTML usando mail () 327
416 Seção 64.3: Enviando email com um anexo usando o mail () 328
417 Seção 64.4: Enviando email de texto simples usando o PHPMailer 329
418 Seção 64.5: Enviando email em HTML usando o PHPMailer 330
419 Seção 64.6: Enviando email com um anexo usando o PHPMailer 331
420 Seção 64.7: Enviando email de texto sem formatação usando o Sendgrid 331
421 Seção 64.8: Enviando email com um anexo usando o Sendgrid 332
422 Capítulo 65: Usando o SQLSRV 333
423 Seção 65.1: Recuperando mensagens de erro 333
424 Seção 65.2: Obtendo resultados da consulta 333
425 Seção 65.3: Criando uma conexão 334
426 Seção 65.4: Fazendo uma consulta simples 334
427 Seção 65.5: Chamando um procedimento armazenado 334
428 Seção 65.6: Fazendo uma consulta parametrizada 335
429 Capítulo 66: Interface de linha de comando (CLI) 336
430 Seção 66.1: Manipulando as opções do programa 336
431 Seção 66.2: Manipulação de argumentos 337
432 Seção 66.3: Manuseio de entrada e saída 338
433 Seção 66.4: Códigos de Retorno 339
434 Seção 66.5: Restringir a execução de scripts à linha de comando 339
435 Seção 66.6: Diferenças comportamentais na linha de comando 339
436 Seção 66.7: Executando seu script 340
437 Seção 66.8: Casos de Borda de getopt () 340
438 Seção 66.9: Executando o servidor da Web incorporado 341
439 Capítulo 67: Localização 343
440 Seção 67.1: Localizando strings com gettext () 343
441 Capítulo 68: Manipulação de cabeçalhos 344
442 Seção 68.1: Configuração Básica de um Cabeçalho 344
443 Capítulo 69: Convenções de Codificação 345
444 Seção 69.1: Tags do PHP 345
445 Capítulo 70: Programação Assíncrona 346
446 Seção 70.1: Vantagens dos Geradores 346
447 Seção 70.2: Usando o loop de eventos Icicle 346
448 Seção 70.3: Gerando processos sem bloqueio com proc_open () 347
449 Seção 70.4: Leitura da porta serial com evento e DIO 348
450 Seção 70.5: Cliente HTTP com base na extensão de evento 350
451 Seção 70.6: Cliente HTTP Baseado na Extensão Ev 353
452 Seção 70.7: Usando o loop de eventos do Amp 357
453 Capítulo 71: Como Detectar o Endereço IP do Cliente 359
454 Seção 71.1: Uso adequado de HTTP_X_FORWARDED_FOR 359
455 Capítulo 72: Criar arquivos PDF no PHP 361
456 Seção 72.1: Introdução ao PDFlib 361
457 FF
458 Capítulo 73: YAML em PHP 362
459 Seção 73.1: Instalando a extensão YAML 362
460 Seção 73.2: Usando o YAML para armazenar a configuração do aplicativo 362
461 Capítulo 74: Processamento de Imagem com o GD 364
462 Seção 74.1: Saída da imagem 364
463 Seção 74.2: Criando uma imagem 365
464 Seção 74.3: Recorte e redimensionamento de imagens 366
465 Capítulo 75: Imagick 369
466 Seção 75.1: Primeiros Passos 369
467 Seção 75.2: Converter imagem em string base64 369
468 Capítulo 76: Servidor SOAP 371
469 Seção 76.1: Servidor SOAP básico 371
470 Capítulo 77: Aprendizado de Máquina 372
471 Seção 77.1: Classificação usando PHPML 372
472 Seção 77.2: Regressão 373
473 Seção 77.3: Clustering 375
474 Capítulo 78: Cache 377
475 Seção 78.1: Armazenamento em cache usando memcache 377
476 Seção 78.2: Cache usando cache APC 378
477 Capítulo 79: Primer de Carregamento Automático 380
478 Seção 79.1: Carregamento automático como parte de uma solução de estrutura 380
479 Seção 79.2: Definição da classe Inline, sem necessidade de carregamento 380
480 Seção 79.3: Carregamento de classe manual com require 381
481 Seção 79.4: O Carregamento Automático substitui o carregamento manual de definição
de classe 381
482 Seção 79.5: Carregamento automático com o Composer 382
483 Capítulo 80: Estruturas de dados SPL 383
484 Seção 80.1: SplFixedArray 383
485 Capítulo 81: IMAP 387
486 Seção 81.1: Conectando a uma caixa postal 387
487 Seção 81.2: Instalar extensão IMAP 388
488 Seção 81.3: Listar todas as pastas na caixa de correio 388
489 Seção 81.4: Localizando mensagens na caixa postal 389
490 Capítulo 82: Autenticação HTTP 391
491 Seção 82.1: Autenticação simples 391
492 Capítulo 83: WebSockets 392
493 Seção 83.1: Servidor TCP /IP Simples 392
494 Capítulo 84: Matemática BC (calculadora binária) 394
495 Seção 84.1: Usando o bcmath para ler /gravar um arquivo binário longo no sistema de
32 bits 394
496 Seção 84.2: Comparação entre o BCMath e operações aritméticas float 395
497 Capítulo 85: Implantação do Docker 397
498 Seção 85.1: Obter imagem do docker para php 397
499 Seção 85.2: Escrevendo o dockerfile 397
500 Seção 85.3: Construindo a imagem 397
501 Seção 85.4: Iniciando o contêiner de aplicativos 398
502 Capítulo 86: APCu 399
503 Seção 86.1: Iterando Entradas 399
504 Seção 86.2: Armazenamento e recuperação simples 399
505 Seção 86.3: Armazenar informações 399
506 FF
507 Capítulo 87: PHP Construído no servidor 400
508 Seção 87.1: Executando o servidor embutido 400
509 Seção 87.2: construído no servidor com diretório específico e roteador script 400
510 Capítulo 88: PSR 401
511 Seção 88.1: PSR4: Autoloader 401
512 Seção 88.2: PSR1: Padrão Básico de Codificação 402
513 Capítulo 89: PHPDoc 403
514 Seção 89.1: Descrevendo uma variável 403
515 Seção 89.2: Adicionando metadados às funções 403
516 Seção 89.3: Descrição dos parâmetros 404
517 Seção 89.4: Coleções 405
518 Seção 89.5: Adicionando metadados aos arquivos 406
519 Seção 89.6: Herdando metadados de estruturas pai 406
520 Capítulo 90: Padrões de Design 408
521 Seção 90.1: Encadeamento de Método no PHP 408
522 Capítulo 91: Compile Extensões PHP 410
523 Seção 91.1: Compilando no Linux 410
524 Capítulo 92: Erros Comuns 411
525 Seção 92.1: Chamar fetch_assoc em booleano 411
526 Seção 92.2: Fim inesperado de $ 411
527 Capítulo 93: Compilação de Erros e Avisos 413
528 Seção 93.1: Erro de análise: erro de sintaxe, inesperado T_PAAMAYIM_NEKUDOTAYIM 413
529 Seção 93.2: Aviso: Índice indefinido 413
530 Seção 93.3: Aviso: Não é possível modificar as informações do cabeçalho cabeçalhos
já enviados 413
531 Capítulo 94: Tratamento de Exceção e Relatório de Erros 415
532 Seção 94.1: Configurando relatórios de erros e onde exibilos 415
533 Seção 94.2: Registrando erros fatais 415
534 Capítulo 95: Depuração 417
535 Seção 95.1: Variáveis de despejo 417
536 Seção 95.2: Exibindo erros 417
537 Seção 95.3: phpinfo () 418
538 Seção 95.4: Xdebug 418
539 Seção 95.5: Relatório de Erros (use ambos) 419
540 Seção 95.6: phpversion () 419
541 Capítulo 96: Testes Unitários 420
542 Seção 96.1: Testando as regras de classe 420
543 Seção 96.2: Provedores de Dados do PHPUnit 423
544 Seção 96.3: Exceções de teste 426
545 Capítulo 97: Desempenho 428
546 Seção 97.1: Criação de perfil com o Xdebug 428
547 Seção 97.2: Uso da Memória 429
548 Seção 97.3: Criação de perfil com o XHProf 430
549 Capítulo 98: Multiprocessamento 432
550 Seção 98.1: Multiprocessamento usando funções de garfo embutidas 432
551 Seção 98.2: Criando um processo filho usando fork 432
552 Seção 98.3: Comunicação entre processos 433
553 Capítulo 99: Extensão MultiThreading 434
554 Seção 99.1: Começando 434
555 FF
556 Seção 99.2: Usando Piscinas e Trabalhadores 434
557 Capítulo 100: Secure Remeber Me 436
558 Seção 100.1: “Mantenhame conectado” a melhor abordagem 436
559 Capítulo 101: Segurança 437
560 Seção 101.1: Vazamento da Versão do PHP 437
561 Seção 101.2: Scripts entre sites (XSS) 437
562 Seção 101.3: Falsificação de Solicitação entre Sites 439
563 Seção 101.4: Injeção de Linha de Comando 440
564 Seção 101.5: Tags de Decapagem 441
565 Seção 101.6: Inclusão de arquivos 442
566 Seção 101.7: Relatório de Erros 442
567 Seção 101.8: Carregando arquivos 443
568 Capítulo 102: Criptografia 446
569 Seção 102.1: Criptografia e descriptografia simétricas de arquivos grandes com
OpenSSL 446
570 Seção 102.2: Cifra Simétrica 448
571 Capítulo 103: Funções de Hashing de Senha 449
572 Seção 103.1: Criando um hash de senha 449
573 Seção 103.2: Determine se um hash de senha existente pode ser atualizado para um
algoritmo mais forte 450
574 Seção 103.3: Verificando uma senha contra um hash 451
575 Capítulo 104: Contribuindo com o Manual PHP 452
576 Seção 104.1: Melhorar a documentação oficial 452
577 Seção 104.2: Dicas para contribuir com o manual 452
578 Capítulo 105: Contribuindo para o núcleo do PHP 453
579 Seção 105.1: Configurando um ambiente de desenvolvimento básico 453
580 Apêndice A: Instalando um ambiente PHP no Windows 454
581 Seção A.1: Faça o download, instale e use o WAMP 454
582 Seção A.2: Instalar o PHP e usálo com o IIS 454
583 Seção A.3: Baixar e instalar o XAMPP 455
584 Apêndice B: Instalando em Ambientes Linux /Unix 458
585 Seção B.1: Instalação da linha de comando usando o APT para PHP 7 458
586 Seção B.2: Instalando nas distribuições do Enterprise Linux (CentOS, Scientific
Linux, etc) 458
587 Créditos 460
588 Você pode gostar 468
589 FF
590 Notas PHP para profissionais 1
591 Sobre
592 Por favor, sintase livre para compartilhar este PDF com qualquer um de graça,
593 A última versão deste livro pode ser baixada em:
594 https://goalkicker.com/PHPBook
595 Este livro do PHP Notes for Professionals é compilado a partir do Stack Overflow
596 Documentação, o conteúdo é escrito por pessoas bonitas no Stack Overflow
597 O conteúdo do texto é liberado sob Creative Commons BYSA, veja os créditos no final
598 deste livro que contribuiu para os vários capítulos Imagens podem ser copyright
599 de seus respectivos proprietários, salvo indicação em contrário
600 Este é um livro gratuito não oficial criado para fins educacionais e não é
601 afiliado ao (s) grupo (s) oficial (is) do PHP ou empresa (s), nem ao Stack Overflow
Todos
602 marcas comerciais e registradas são de propriedade de seus respectivos
603 proprietários de empresas
604 A informação apresentada neste livro não é garantida como correta nem
605 preciso, use a seu próprio risco
606 Por favor envie feedback e correções para web@petercv.com
607 FF
608 Notas PHP para Profissionais 2
609 Capítulo 1: Introdução ao PHP
610 PHP 7.x
611 Versão suportada até a data de lançamento
612 7,1 20191201 20161201
613 7,0 20181203 20151203
614 PHP 5.x
615 Versão suportada até a data de lançamento
616 5,6 20181231 20140828
617 5.5 20160721 20130620
618 5.4 20150903 20120301
619 5.3 20140814 20090630
620 5.2 20110106 20061102
621 5.1 20060824 20051124
622 5.0 20050905 20040713
623 PHP 4.x
624 Versão suportada até a data de lançamento
625 4.4 20080807 20050711
626 4.3 20050331 20021227
627 4.2 20020906 20020422
628 4.1 20020312 20011210
629 4.0 20010623 20000522
630 Versões Legadas
631 Versão suportada até a data de lançamento
632 3.0 20001020 19980606
633 2.0 19971101
634 1.0 19950608
635 Seção 1.1: saída HTML do servidor da web
636 O PHP pode ser usado para adicionar conteúdo a arquivos HTML Enquanto o HTML é
processado diretamente por um navegador da Web, scripts PHP são
637 executado por um servidor web e o HTML resultante é enviado para o navegador
638 A seguinte marcação HTML contém uma instrução PHP que adicionará Hello World! para a
saída:
639 <! DOCTYPE html>
640 <html>
641 <cabeça>
642 <title> PHP! </title>
643 </head>
644 <body>
645 <p> <?phpecho "Olá, mundo!"; ?> </p>
646 </body>
647 </html>
648 Quando isso é salvo como um script PHP e executado por um servidor web, o seguinte
HTML será enviado para o usuário
649 navegador:
650 <! DOCTYPE html>
651 <html>
652 <cabeça>
653 FF
654 Notas PHP para Profissionais 3
655 <title> PHP! </title>
656 </head>
657 <body>
658 <p> Olá, mundo! </p>
659 </body>
660 </html>
661 Versão do PHP 5.x = 5.4
662 O echo também possui uma sintaxe de atalho, que permite imprimir imediatamente um
valor Antes do PHP 5.4.0, esta sintaxe curta apenas
663 funciona com a configuração de configuração short_open_tag ativada
664 Por exemplo, considere o seguinte código:
665 <p> <? = "Olá mundo!" ?> </p>
666 Sua saída é idêntica à saída do seguinte:
667 <p> <?phpecho "Olá, mundo!"; ?> </p>
668 Em aplicações do mundo real, toda a saída de dados pelo PHP para uma página HTML
deve ser adequadamente escapada para evitar XSS
669 (Crosssite scripting) ataques ou corrupção de texto
670 Veja também: Strings e PSR1, que descreve as melhores práticas, incluindo o uso
adequado de tags curtas (<? = ...?>)
671 Seção 1.2: Olá, mundo!
672 A construção de linguagem mais usada para imprimir a saída no PHP é o eco:
673 echo "Olá, mundo! \ n";
674 Como alternativa, você também pode usar impressão:
675 print "Olá, mundo! \ n";
676 Ambas as declarações executam a mesma função, com pequenas diferenças:
677 o eco tem um retorno nulo, enquanto a impressão retorna um int com um valor de 1
678 O echo pode ter vários argumentos (sem parênteses), enquanto que a impressão leva
apenas um argumento
679 o eco é um pouco mais rápido que imprimir
680 O eco e a impressão são construções de linguagem, não funções Isso significa que
eles não exigem parênteses
681 seus argumentos Para consistência cosmética com funções, parênteses podem ser
incluídos Exemplos extensivos do
682 o uso de eco e impressão está disponível em outros lugares
683 O printf em estilo C e as funções relacionadas também estão disponíveis, como no
exemplo a seguir:
684 printf ("% s \ n", "Olá, mundo!");
685 Veja Saída do valor de uma variável para uma introdução abrangente de variáveis de
saída no PHP
686 Seção 1.3: Saída não HTML do servidor da web
687 Em alguns casos, ao trabalhar com um servidor da Web, pode ser necessário substituir
o tipo de conteúdo padrão do servidor da Web
688 Pode haver casos em que você precise enviar dados como texto simples, JSON ou XML,
por exemplo.
689 FF
690 Notas PHP para Profissionais 4
691 A função header () pode enviar um cabeçalho HTTP bruto Você pode adicionar o
cabeçalho ContentType para notificar o navegador de
692 o conteúdo que estamos enviando
693 Considere o seguinte código, onde definimos ContentType como text /plain:
694 cabeçalho ("ContentType: text /plain");
695 eco "Olá mundo";
696 Isso produzirá um documento de texto simples com o seguinte conteúdo:
697 Olá Mundo
698 Para produzir conteúdo JSON, use o tipo de conteúdo application /json:
699 cabeçalho ("ContentType: application /json");
700 //Cria uma matriz de dados PHP
701 $data = ["response" => "Olá mundo"];
702 //json_encode irá convertêlo para uma string JSON válida
703 echo json_encode ($data);
704 Isso produzirá um documento do tipo application /json com o seguinte conteúdo:
705 {"response": "Hello World"}
706 Note que a função header () deve ser chamada antes que o PHP produza qualquer saída,
ou o servidor web terá
707 já enviou cabeçalhos para a resposta Então, considere o seguinte código:
708 //Erro: não podemos enviar nenhuma saída antes dos cabeçalhos
709 eco "Olá";
710 //Todos os cabeçalhos devem ser enviados antes de qualquer saída PHP
711 cabeçalho ("ContentType: text /plain");
712 eco "mundo";
713 Isso produzirá um aviso:
714 Aviso: Não é possível modificar as informações do cabeçalho cabeçalhos já enviados
por (saída iniciada em
715 /dir/example.php:2) em /dir/example.php na linha 3
716 Ao usar o header (), sua saída precisa ser o primeiro byte enviado do servidor Por
esta razão, é importante
717 não ter linhas ou espaços vazios no começo do arquivo antes da tag de abertura do
PHP <? php Para o mesmo
718 Por que razão, considerase a melhor prática (ver PSR2) omitir a tag de fechamento do
PHP?> de arquivos que contêm apenas PHP e
719 de blocos de código PHP no final de um arquivo
720 Veja a seção de buffer de saída para aprender como "capturar" seu conteúdo em uma
variável para produzir mais tarde, por exemplo,
721 após a saída de cabeçalhos.
722 FF
723 Notas PHP para Profissionais 5
724 Seção 1.4: Servidor Interno do PHP
725 O PHP 5.4+ vem com um servidor de desenvolvimento embutido Pode ser usado para
executar aplicativos sem ter que instalar um
726 servidor HTTP de produção, como nginx ou Apache O servidor embutido é projetado
apenas para ser usado para desenvolvimento
727 e fins de teste
728 Pode ser iniciado usando o sinalizador S:
729 php S <host /ip>: <porta>
730 Exemplo de uso
731 1 Crie um arquivo index.php contendo:
732 <?php
733 echo "Hello World do servidor PHP embutido";
734 2 Execute o comando php S localhost: 8080 na linha de comando Não inclui
735 http: //
736 Isso iniciará um servidor da Web escutando na porta 8080 usando o diretório atual
em que você está
737 raiz do documento
738 3 Abra o navegador e navegue até http: //localhost: 8080 Você deve ver sua página
"Hello World".
739 Configuração
740 Para substituir a raiz do documento padrão (ou seja, o diretório atual), use o
sinalizador t:
741 php S <host /ip>: <porta> t <diretório>
742 Por exemplo, se você tem um diretório /public em seu projeto, você pode servir seu
projeto a partir desse diretório usando php S
743 localhost: 8080 t público /
744 Logs
745 Toda vez que uma solicitação é feita a partir do servidor de desenvolvimento, uma
entrada de log como a abaixo é gravada no
746 linha de comando
747 [Seg Ago 15 18:20:19 2016] :: 1: 52455 [200]: /
748 Seção 1.5: CLI do PHP
749 O PHP também pode ser executado diretamente da linha de comando usando o CLI
(Command Line Interface)
750 O CLI é basicamente igual ao PHP dos servidores da Web, exceto algumas diferenças em
termos de entrada e saída padrão
751 Triggering
752 O PHP CLI permite quatro maneiras de executar o código PHP:
753 1 entrada padrão Execute o comando php sem nenhum argumento, mas insira o código PHP
nele: echo '<?phpecho
754 "Olá Mundo!";' | php
755 2 Nome do arquivo como argumento Execute o comando php com o nome de um arquivo
fonte do PHP como o primeiro argumento: php
756 hello_world.php
757 FF
758 Notas PHP para Profissionais 6
759 3 Código como argumento Use a opção r no comando php, seguido pelo código a ser
executado As tags abertas <? Php
760 não são necessários, já que tudo no argumento é considerado como código PHP: php r
'echo "Hello world!";'
761 4 shell interativo Use a opção a no comando php para iniciar um shell interativo Em
seguida, digite (ou cole)
762 Código PHP e pressione Enter: $php a Modo interativo habilitado php> echo "Hello
world!"; Olá Mundo!
763 Saída
764 Todas as funções ou controles que produzem saída HTML no servidor web PHP podem ser
usadas para produzir saída no stdout
765 stream (descritor de arquivo 1), e todas as ações que produzem saída em logs de
erros no servidor web PHP produzirão saída em
766 o fluxo stderr (descritor de arquivo 2)
767 Example.php
768 <?php
769 echo "Stdout 1 \ n";
770 trigger_error ("Stderr 2 \ n");
771 print_r ("padrão 3 \ n");
772 fwrite (STDERR, "Stderr 4 \ n");
773 throw new RuntimeException ("Stderr 5 \ n");
774 ?>
775 Stdout 6
776 Linha de comando da Shell
777 $php Example.php 2> stderr.log> stdout.log; \
778 > echo STDOUT; cat stdout.log; eco;\
779 > echo STDERR; cat stderr.log \
780 STDOUT
781 Stdout 1
782 Stdout 3
783 STDERR
784 Stderr 4
785 Nota do PHP: Stderr 2
786 em /Example.php na linha 3
787 Erro Fatal do PHP: RuntimeException Não Capturado: Stderr 5
788 em /Exemplo.php:6
789 Rastreamento de pilha:
790 # 0 {main}
791 lançada em /Example.php na linha 6
792 Entrada
793 Veja: Interface de Linha de Comando (CLI)
794 Seção 1.6: Separação de Instrução
795 Assim como a maioria das outras linguagens no estilo C, cada instrução é terminada
com um ponto e vírgula Além disso, uma tag de fechamento é usada para
796 terminar a última linha de código do bloco PHP
797 Se a última linha do código PHP terminar com um pontoevírgula, a tag de fechamento
será opcional se não houver código após o final
798 linha de código Por exemplo, podemos deixar de fora a tag de fechamento após o echo
"No error"; no exemplo a seguir:
799 <?phpecho "Nenhum erro"; //nenhuma tag de fechamento é necessária, desde que não
haja código abaixo
800 No entanto, se houver qualquer outro código após seu bloco de código PHP, a tag de
fechamento não será mais opcional:
801 <?phpecho "Isso causará um erro se você deixar de fora a tag de fechamento"; ?>
802 <html>
803 <body>
804 FF
805 Notas PHP para Profissionais 7
806 </body>
807 </html>
808 Também podemos deixar de fora o pontoevírgula da última instrução em um bloco de
código PHP se esse bloco de código tiver uma tag de fechamento:
809 <?phpecho "Espero que isso ajude!: D";
810 eco "Nenhum erro"?>
811 Geralmente é recomendado usar sempre um pontoevírgula e usar uma tag de fechamento
para cada bloco de código PHP, exceto o
812 último bloco de código PHP, se nenhum outro código seguir esse bloco de código PHP
813 Então, seu código deve basicamente ficar assim:
814 <?php
815 echo "Aqui usamos um ponto e vírgula!";
816 eco "Aqui também!";
817 eco "Aqui também!";
818 echo "Aqui usamos um pontoevírgula e uma tag de fechamento porque mais código segue";
819 ?>
820 <p> Algum código HTML vai aqui </p>
821 <?php
822 echo "Aqui usamos um ponto e vírgula!";
823 eco "Aqui também!";
824 eco "Aqui também!";
825 echo "Aqui usamos um pontoevírgula e uma tag de fechamento porque mais código segue";
826 ?>
827 <p> Algum código HTML vai aqui </p>
828 <?php
829 echo "Aqui usamos um ponto e vírgula!";
830 eco "Aqui também!";
831 eco "Aqui também!";
832 echo "Aqui usamos um pontoevírgula, mas deixamos de fora a tag de fechamento";
833 Seção 1.7: Tags do PHP
834 Existem três tipos de tags para denotar blocos PHP em um arquivo O analisador PHP
está procurando pela abertura e (se
835 presente) tags de fechamento para delimitar o código a ser interpretado
836 Tags padrão
837 Essas tags são o método padrão para incorporar código PHP em um arquivo
838 <?php
839 eco "Olá mundo";
840 ?>
841 Versão do PHP 5.x = 5.4
842 Tags de eco
843 Estas tags estão disponíveis em todas as versões do PHP, e desde o PHP 5.4 estão
sempre ativadas Nas versões anteriores, as tags de eco
844 só pode ser ativado em conjunto com tags curtas
845 <? = "Hello World"?>
846 Tags curtas
847 Você pode desativar ou ativar essas tags com a opção short_open_tag.
848 FF
849 Notas PHP para Profissionais 8
850 <?
851 eco "Olá mundo";
852 ?>
853 Tags curtas:
854 não são permitidos em todos os principais padrões de codificação PHP
855 são desencorajados na documentação oficial
856 estão desativados por padrão na maioria das distribuições
857 Interferir com as instruções de processamento do XML embutido
858 não são aceitos em envios de código pela maioria dos projetos de código aberto
859 Versão do PHP 5.x = 5.6
860 Tags ASP
861 Ao ativar a opção asp_tags, as tags de estilo ASP podem ser usadas
862 <%
863 eco "Olá mundo";
864 %>
865 Estas são uma peculiaridade histórica e nunca devem ser usadas Eles foram removidos
no PHP 7.0.
866 FF
867 Notas PHP para Profissionais 9
868 Capítulo 2: Variáveis
869 Seção 2.1: Acessando uma variável dinamicamente por nome
870 (Variáveis variáveis)
871 Variáveis podem ser acessadas através de nomes de variáveis dinâmicas O nome de uma
variável pode ser armazenado em outra variável,
872 permitindo que seja acessado dinamicamente Essas variáveis são conhecidas como
variáveis variáveis.
873 Para transformar uma variável em variável variável, você coloca um $extra na frente
da sua variável
874 $variableName = 'foo';
875 $foo = 'bar';
876 //Os seguintes são todos equivalentes e todos os output "bar":
877 echo $foo;
878 echo ${$variávelName};
879 echo $$variableName;
880 //similarmente,
881 $variableName = 'foo';
882 $$variableName = 'bar';
883 //As seguintes declarações também irão mostrar 'bar'
884 echo $foo;
885 echo $$variableName;
886 echo ${$variávelName};
887 Variáveis variáveis são úteis para mapear chamadas de função /método:
888 função add ($a, $b) {
889 devolve $a + $b;
890 }
891 $funcName = 'add';
892 echo $funcName (1, 2); //saídas 3
893 Isso se torna particularmente útil em classes PHP:
894 class myClass {
895 função pública __construct () {
896 $functionName = 'doSomething';
897 $this > $functionName ('Hello World');
898 }
899 função privada doSomething ($string) {
900 echo $string; //Saídas "Hello World"
901 }
902 }
903 É possível, mas não obrigatório, colocar $variableName entre {}:
904 ${$variableName} = $valor;
905 Os exemplos a seguir são equivalentes e produzem "baz":
906 $fooBar = 'baz';
907 FF
908 Notas PHP para Profissionais 10
909 $varPrefix = 'foo';
910 echo $fooBar; //Saídas "baz"
911 echo ${$varPrefix 'Barra'}; //Também produz "baz"
912 O uso de {} é obrigatório apenas quando o nome da variável é uma expressão, como
esta:
913 ${$variableNamePart1 $variableNamePart2} = $value;
914 No entanto, é recomendável usar sempre {}, porque é mais legível
915 Embora não seja recomendado fazer isso, é possível encadear esse comportamento:
916 $$$$$$$$DoNotTryThisAtHomeKids = valor $;
917 É importante notar que o uso excessivo de variáveis variáveis é considerado uma
prática ruim por muitos
918 desenvolvedores Como eles não são adequados para análise estática por IDEs modernos,
grandes bases de código com muitos
919 variáveis variáveis (ou invocações de método dinâmico) podem rapidamente se tornar
difíceis de manter
920 Diferenças entre PHP5 e PHP7
921 Outra razão para usar sempre {} ou (), é que PHP5 e PHP7 têm uma maneira
ligeiramente diferente de lidar com a dinâmica
922 variáveis, o que resulta em um resultado diferente em alguns casos
923 No PHP7, variáveis dinâmicas, propriedades e métodos serão agora avaliados
estritamente da esquerda para a direita, ao contrário
924 para o mix de casos especiais no PHP5 Os exemplos abaixo mostram como a ordem de
avaliação foi alterada.
925 Caso 1: $$foo ['bar'] ['baz']
926 Interpretação do PHP5: ${$foo ['bar'] ['baz']}
927 Interpretação do PHP7: ($$foo) ['bar'] ['baz']
928 Caso 2: $foo > $bar ['baz']
929 Interpretação do PHP5: $foo > {$bar ['baz']}
930 Interpretação PHP7: ($foo > $bar) ['baz']
931 Caso 3: $foo > $bar ['baz'] ()
932 Interpretação do PHP5: $foo > {$bar ['baz']} ()
933 Interpretação PHP7: ($foo > $bar) ['baz'] ()
934 Caso 4: Foo :: $bar ['baz'] ()
935 Interpretação do PHP5: Foo :: {$bar ['baz']} ()
936 Interpretação do PHP7: (Foo :: $bar) ['baz'] ()
937 Seção 2.2: Tipos de Dados
938 Existem diferentes tipos de dados para finalidades diferentes O PHP não possui
definições de tipo explícitas, mas o tipo de
939 variável é determinada pelo tipo do valor atribuído ou pelo tipo para o qual é
transmitido Este é um breve
940 visão geral sobre os tipos, para uma documentação detalhada e exemplos, veja o
tópico Tipos de PHP
941 Existem os seguintes tipos de dados no PHP: null, boolean, integer, float, string,
objeto, recurso e array.
942 FF
943 Notas PHP para Profissionais 11
944 Nulo
945 Nulo pode ser atribuído a qualquer variável Representa uma variável sem valor.
946 $foo = null;
947 Isso invalida a variável e seu valor seria indefinido ou inválido se chamado A
variável é apagada da memória
948 e excluído pelo coletor de lixo
949 boleano
950 Este é o tipo mais simples com apenas dois valores possíveis
951 $foo = true;
952 $bar = false;
953 Booleans podem ser usados para controlar o fluxo de código
954 $foo = true;
955 if ($foo) {
956 eco "verdadeiro";
957 } outro {
958 eco "falso";
959 }
960 Inteiro
961 Um inteiro é um número inteiro positivo ou negativo Pode ser usado com qualquer base
numérica O tamanho de um inteiro é
962 dependente da plataforma O PHP não suporta números inteiros sem sinal.
963 $foo = 3; //negativo
964 $foo = 0; //zero (também pode ser nulo ou falso (como booleano)
965 $foo = 123; //decimal positivo
966 $bar = 0123; //octal = 83 decimal
967 $bar = 0xAB; //hexadecimal = 171 decimal
968 $bar = 0b1010; //binário = 10 decimal
969 var_dump (0123, 0xAB, 0b1010); //output: int (83) int (171) int (10)
970 Flutuador
971 Números de pontos flutuantes, "duplos" ou simplesmente chamados de "carros
alegóricos" são números decimais
972 $foo = 1,23;
973 $foo = 10,0;
974 $bar = INF;
975 $bar = NAN;
976 Matriz
977 Uma matriz é como uma lista de valores A forma mais simples de uma matriz é indexada
por inteiro e ordenada pelo índice, com
978 o primeiro elemento deitado no índice 0
979 $foo = array (1, 2, 3); //Uma matriz de inteiros
980 $bar = ["A", verdadeiro, 123 => 5]; //Sintaxe de matriz curta, PHP 5.4+
981 FF
982 Notas PHP para Profissionais 12
983 echo $bar [0]; //Retorna "A"
984 echo $bar [1]; //Retorna true
985 echo $bar [123]; //retorna 5
986 echo $bar [1234]; //Retorna nulo
987 Os arrays também podem associar uma chave diferente de um índice inteiro a um valor
No PHP, todos os arrays são matrizes associativas
988 nos bastidores, mas quando nos referimos a um 'array associativo' distintamente,
geralmente queremos dizer um que contém um ou
989 mais chaves que não são inteiros
990 $array = array ();
991 $array ["foo"] = "barra";
992 $array ["baz"] = "quux";
993 $array [42] = "olá";
994 echo $array ["foo"]; //Outputs "bar"
995 echo $array ["bar"]; //Saídas "quux"
996 echo $array [42]; //Saídas "olá"
997 Corda
998 Uma string é como uma matriz de caracteres
999 $foo = "bar";
1000 Como uma matriz, uma string pode ser indexada para retornar seus caracteres
individuais:
1001 $foo = "bar";
1002 echo $foo [0]; //Imprime 'b', o primeiro caractere da string em $foo.
1003 Objeto
1004 Um objeto é uma instância de uma classe Suas variáveis e métodos podem ser acessados
com o operador >.
1005 $foo = new stdClass (); //cria novo objeto da classe stdClass, que uma classe vazia
predefinida
1006 $foo> bar = "baz";
1007 echo $foo> bar; //Saídas "baz"
1008 //Ou podemos lançar uma matriz para um objeto:
1009 $quux = (objeto) ["foo" => "barra"];
1010 echo $quux> foo; //Isso produz "bar".
1011 Recurso
1012 As variáveis de recurso possuem identificadores especiais para arquivos abertos,
conexões de banco de dados, fluxos, áreas de tela de imagem e
1013 o semelhante (como é indicado no manual)
1014 $fp = fopen ('file.ext', 'r'); //fopen () é a função para abrir um arquivo no disco
como um recurso.
1015 var_dump ($fp); //output: resource (2) do tipo (fluxo)
1016 Para obter o tipo de uma variável como uma string, use a função gettype ():
1017 echo gettype (1); //produz "integer"
1018 echo gettype (true); //"boleano"
1019 FF
1020 Notas PHP para Profissionais 13
1021 Seção 2.3: Melhores práticas de variáveis globais
1022 Podemos ilustrar esse problema com o seguinte pseudocódigo
1023 função foo () {
1024 global $bob;
1025 $bob> doSomething ();
1026 }
1027 Sua primeira pergunta aqui é óbvia
1028 De onde veio o $bob?
1029 Você está confuso? Boa Você acabou de aprender porque os globals são confusos e
considerados uma prática ruim.
1030 Se este fosse um programa real, a sua próxima diversão é ir buscar todas as
instâncias de $bob e esperar encontrar o caminho certo
1031 um (isso fica pior se $bob é usado em todos os lugares) Pior, se alguém vai e define
$bob (ou você esqueceu e
1032 reutilizou essa variável) seu código pode quebrar (no exemplo de código acima, com o
objeto errado, ou nenhum objeto,
1033 causaria um erro fatal)
1034 Já que praticamente todos os programas PHP fazem uso de código como include
('file.php'); seu trabalho de manutenção de código como este
1035 tornase exponencialmente mais difícil quanto mais arquivos você adicionar
1036 Além disso, isso dificulta muito a tarefa de testar seus aplicativos Suponha que
você use uma variável global para manter sua
1037 conexão de banco de dados:
1038 $dbConnector = new DBConnector (...);
1039 função doSomething () {
1040 global $dbConnector;
1041 $dbConnector> execute ("...");
1042 }
1043 Para testar essa função, é necessário substituir a variável global $dbConnector,
executar os testes e, em seguida,
1044 redefinao ao seu valor original, que é muito propenso a erros:
1045 /**
1046 * @teste
1047 */
1048 function testSomething () {
1049 global $dbConnector;
1050 $bkp = $dbConnector; //Faça backup
1051 $dbConnector = Mock :: create ('DBConnector'); //Sobrepor
1052 assertTrue (foo ());
1053 $dbConnector = $bkp; //Restore
1054 }
1055 Como evitamos Globals?
1056 A melhor maneira de evitar globals é uma filosofia chamada Injeção de Dependência É
aqui que passamos as ferramentas que
1057 necessidade para a função ou classe.
1058 FF
1059 Notas PHP para Profissionais 14
1060 função foo (\ Bar $bob) {
1061 $bob> doSomething ();
1062 }
1063 Isso é muito mais fácil de entender e manter Não há como adivinhar onde $bob foi
configurado porque o chamador é
1064 responsável por saber disso (está nos passando o que precisamos saber) Melhor ainda,
podemos usar declarações de tipo para
1065 restringir o que está sendo passado
1066 Então, sabemos que $bob é uma instância da classe Bar ou uma instância de um filho
de Bar, o que significa que sabemos
1067 pode usar os métodos dessa classe Combinado com um autoloader padrão (disponível
desde o PHP 5.3), podemos agora
1068 rastrear onde Bar está definido PHP 7.0 ou posterior inclui declarações de tipo
expandidas, onde você também pode usar
1069 tipos escalares (como int ou string)
1070 Versão = 4.1
1071 Variáveis superglobais
1072 Super globals em PHP são variáveis prédefinidas, que estão sempre disponíveis, podem
ser acessadas de qualquer escopo
1073 em todo o script
1074 Não há necessidade de fazer uma variável $global; para acessálos dentro de funções
/métodos, classes ou arquivos.
1075 Essas variáveis superglobais do PHP estão listadas abaixo:
1076 $GLOBALS
1077 $_SERVER
1078 $_REQUEST
1079 $_POST
1080 $_GET
1081 $_FILES
1082 $_ENV
1083 $_COOKIE
1084 $_SESSION
1085 Seção 2.4: Valores padrão de variáveis não inicializadas
1086 Embora não seja necessário no PHP, é uma boa prática inicializar as variáveis
Variáveis não inicializadas têm
1087 valor padrão de seu tipo, dependendo do contexto em que são usados:
1088 Desconectado E não referenciado
1089 var_dump ($unset_var); //gera NULL
1090 boleano
1091 echo ($unset_bool? "true \ n": "falso \ n"); //saídas 'falsas'
1092 Corda
1093 $unset_str = 'abc';
1094 var_dump ($unset_str); //retorna a string (3) "abc" '
1095 Inteiro
1096 FF
1097 Notas PHP para Profissionais 15
1098 $unset_int + = 25; //0 + 25 => 25
1099 var_dump ($unset_int); //produz 'int (25)'
1100 Flutuante /duplo
1101 $unset_float + = 1,25;
1102 var_dump ($unset_float); //saídas 'float (1.25)'
1103 Matriz
1104 $unset_arr [3] = "def";
1105 var_dump ($unset_arr); //outputs array (1) {[3] => string (3) "def"}
1106 Objeto
1107 $unset_obj> foo = 'bar';
1108 var_dump ($unset_obj); //Saídas: objeto (stdClass) # 1 (1) {["foo"] => string (3)
"bar"}
1109 Confiar no valor padrão de uma variável não inicializada é problemático no caso de
incluir um arquivo em outro
1110 que usa o mesmo nome de variável
1111 Seção 2.5: Veracidade do Valor Variável e Operador Idêntico
1112 No PHP, os valores das variáveis têm uma "autenticidade" associada, de modo que até
valores não booleanos se igualarão a verdadeiro ou falso
1113 Isso permite que qualquer variável seja usada em um bloco condicional, por exemplo
1114 if ($var == true) {/* versão explícita */}
1115 if ($var) {/* $var == verdadeiro é implícito */}
1116 Aqui estão algumas regras fundamentais para diferentes tipos de valores de variáveis:
1117 Strings com comprimento diferente de zero são iguais a true, incluindo strings
contendo apenas espaços em branco como ''
1118 Seqüências vazias '' equivalem a falsas
1119 $var = '';
1120 $var_is_true = ($var == verdadeiro); //false
1121 $var_is_false = ($var == false); //verdade
1122 $var = '';
1123 $var_is_true = ($var == verdadeiro); //verdade
1124 $var_is_false = ($var == false); //false
1125 Os inteiros são iguais a true se forem diferentes de zero, enquanto zero equivale a
false
1126 $var = 1;
1127 $var_is_true = ($var == verdadeiro); //verdade
1128 $var = 99;
1129 $var_is_true = ($var == verdadeiro); //verdade
1130 $var = 0;
1131 $var_is_true = ($var == verdadeiro); //false
1132 null equivale a falso
1133 $var = null;
1134 $var_is_true = ($var == verdadeiro); //false
1135 $var_is_false = ($var == false); //verdade
1136 FF
1137 Notas PHP para Profissionais 16
1138 Strings vazias '' e string zero '0' equivalem a false
1139 $var = '';
1140 $var_is_true = ($var == verdadeiro); //false
1141 $var_is_false = ($var == false); //verdade
1142 $var = '0';
1143 $var_is_true = ($var == verdadeiro); //false
1144 $var_is_false = ($var == false); //verdade
1145 Os valores de ponto flutuante são iguais a true se forem diferentes de zero,
enquanto os valores zero equivalem a false
1146 NAN (PHPnãoumnúmero) equivale a verdadeiro, isto é, NAN == verdadeiro é verdadeiro
Isso ocorre porque a NAN é diferente de zero
1147 valor de ponto flutuante
1148 Valores zero incluem tanto +0 e 0 como definidos pelo IEEE 754 O PHP não distingue
entre +0 e 0
1149 em seu ponto flutuante de precisão dupla, isto é, floatval ('0') == floatval (' 0')
é true
1150 De fato, floatval ('0') === floatval (' 0')
1151 Além disso, ambos floatval ('0') == false e floatval (' 0') == false
1152 $var = NAN;
1153 $var_is_true = ($var == verdadeiro); //verdade
1154 $var_is_false = ($var == false); //false
1155 $var = floatval (' 0');
1156 $var_is_true = ($var == verdadeiro); //false
1157 $var_is_false = ($var == false); //verdade
1158 $var = floatval ('0') == floatval (' 0');
1159 $var_is_true = ($var == verdadeiro); //false
1160 $var_is_false = ($var == false); //verdade
1161 OPERADOR IDÊNTICO
1162 Na documentação do PHP para operadores de comparação, existe um operador idêntico
=== Este operador pode ser usado
1163 para verificar se uma variável é idêntica a um valor de referência:
1164 $var = null;
1165 $var_is_null = $var === null; //verdade
1166 $var_is_true = $var === true; //false
1167 $var_is_false = $var === false; //false
1168 Tem um correspondente operador não idêntico! ==:
1169 $var = null;
1170 $var_is_null = $var! == null; //false
1171 $var_is_true = $var! == verdadeiro; //verdade
1172 $var_is_false = $var! == false; //verdade
1173 O operador idêntico pode ser usado como uma alternativa para funções de linguagem
como is_null ()
1174 USE CASE COM CAMISAS ()
1175 A função de linguagem strpos ($haystack, $needle) é usada para localizar o índice no
qual $needle ocorre em
1176 $palheiro, ou se ocorre de todo A função strpos () é sensível a maiúsculas e
minúsculas; se encontrar maiúsculas e minúsculas é o que você
1177 preciso que você possa ir com stripos ($palheiro, $agulha)
1178 A função strpos & stripos também contém o terceiro parâmetro offset (int) que, se
especificado, a pesquisa iniciará este
1179 número de caracteres contados desde o início da string Ao contrário de strrpos e
strripos, o deslocamento não pode ser
1180 FF
1181 Notas PHP para Profissionais 17
1182 negativo
1183 A função pode retornar:
1184 0 se $agulha for encontrado no começo de $palheiro;
1185 um inteiro diferente de zero especificando o índice se $needle for encontrado em
algum lugar diferente do início
1186 $palheiro;
1187 e valor false se $needle não for encontrado em nenhum lugar no $haystack
1188 Porque ambos 0 e false têm veracidade falsa em PHP mas representam situações
distintas para strpos (), é
1189 importante distinguir entre eles e usar o operador idêntico === para procurar
exatamente por falso e não apenas
1190 valor que equivale a falso
1191 $idx = substr ($palheiro, $agulha);
1192 if ($idx === false)
1193 {
1194 //lógica para quando $needle não encontrado em $haystack
1195 }
1196 outro
1197 {
1198 //lógica para quando $needle encontrado em $haystack
1199 }
1200 Como alternativa, usando o operador não idêntico:
1201 $idx = substr ($palheiro, $agulha);
1202 if ($idx! == falso)
1203 {
1204 //lógica para quando $needle encontrado em $haystack
1205 }
1206 outro
1207 {
1208 //lógica para quando $needle não encontrado em $haystack
1209 }
1210 FF
1211 Notas PHP para Profissionais 18
1212 Capítulo 3: Escopo Variável
1213 Escopo variável referese às regiões de código onde uma variável pode ser acessada
Isso também é chamado de visibilidade Em
1214 Os blocos de escopo do PHP são definidos por funções, classes e um escopo global
disponível em todo o aplicativo
1215 Seção 3.1: Variáveis superglobais
1216 Variáveis superglobais são definidas pelo PHP e sempre podem ser usadas de qualquer
lugar sem a palavrachave global
1217 <?php
1218 function getPostValue ($key, $default = NULL) {
1219 //$_POST é um superglobal e pode ser usado sem
1220 //ter que especificar 'global $_POST;'
1221 if (isset ($_ POST [$key])) {
1222 return $_POST [$key];
1223 }
1224 return $default;
1225 }
1226 //recupera $_POST ['username']
1227 echo getPostValue ('username');
1228 //recupera $_POST ['email'] e usa como padrão string vazia
1229 echo getPostValue ('email', '');
1230 Seção 3.2: Propriedades estáticas e variáveis
1231 As propriedades de classe estática definidas com a visibilidade pública são
funcionalmente as mesmas que as variáveis globais Eles
1232 pode ser acessado de qualquer lugar em que a classe esteja definida
1233 class SomeClass {
1234 public static int $counter = 0;
1235 }
1236 //A variável $contador estática pode ser lida /escrita de qualquer lugar
1237 //e não requer uma instanciação da classe
1238 SomeClass :: $counter + = 1;
1239 Funções também podem definir variáveis estáticas dentro de seu próprio escopo Estas
variáveis estáticas persistem através de múltiplos
1240 chamadas de função, ao contrário de variáveis regulares definidas em um escopo de
função Esta pode ser uma maneira muito fácil e simples de
1241 implementar o padrão de design Singleton:
1242 classe Singleton {
1243 public static function getInstance () {
1244 //Variável estática $instance não é excluída quando a função termina
1245 instância $estática;
1246 //Segunda chamada para esta função não vai entrar na declaração if,
1247 //Porque uma instância do Singleton agora está armazenada na instância $
1248 //variável e é persistida por meio de várias chamadas
1249 if (! $instance) {
1250 //A primeira chamada para esta função alcançará esta linha,
1251 //porque a instância $só foi declarada, não inicializada
1252 $instance = new Singleton ();
1253 }
1254 FF
1255 Notas PHP para Profissionais 19
1256 return $instance;
1257 }
1258 }
1259 $instance1 = Singleton :: getInstance ();
1260 $instance2 = Singleton :: getInstance ();
1261 //A comparação de objetos com o operador '===' verifica se eles são
1262 //a mesma instância Vai imprimir 'true', porque a instância $estática
1263 //a variável no método getInstance () é persistida por meio de várias chamadas
1264 var_dump ($instance1 === $instance2);
1265 Seção 3.3: Variáveis globais definidas pelo usuário
1266 O escopo fora de qualquer função ou classe é o escopo global Quando um script PHP
inclui outro (usando incluir
1267 ou exigir) o escopo permanece o mesmo Se um script é incluído fora de qualquer
função ou classe, são variáveis globais
1268 estão incluídos no mesmo escopo global, mas se um script é incluído a partir de uma
função, as variáveis incluídas
1269 script estão no escopo da função
1270 Dentro do escopo de uma função ou método de classe, a palavrachave global pode ser
usada para criar um acesso definido pelo usuário
1271 variáveis globais
1272 <?php
1273 $amount_of_log_calls = 0;
1274 função log_message ($message) {
1275 //Acessando a variável global do escopo da função
1276 //requer esta declaração explícita
1277 global $amount_of_log_calls;
1278 //Esta mudança para a variável global é permanente
1279 $amount_of_log_calls + = 1;
1280 echo $message;
1281 }
1282 //Quando no escopo global, variáveis globais regulares podem ser usadas
1283 //sem explicitamente declarar 'global $variable;'
1284 echo $amount_of_log_calls; //0
1285 log_message ("Primeira mensagem de log!");
1286 echo $amount_of_log_calls; //1
1287 log_message ("Segunda mensagem de log!");
1288 echo $amount_of_log_calls; //2
1289 Uma segunda maneira de acessar variáveis do escopo global é usar o array especial
$GLOBALS definido pelo PHP
1290 O array $GLOBALS é um array associativo com o nome da variável global sendo a chave
e o conteúdo do
1291 essa variável é o valor do elemento da matriz Observe como o $GLOBALS existe em
qualquer escopo, isso é porque
1292 $GLOBALS é um superglobal
1293 Isso significa que a função log_message () pode ser reescrita como:
1294 função log_message ($message) {
1295 //Acessar a variável global $amount_of_log_calls via
1296 //array $GLOBALS Não há necessidade de 'global $GLOBALS;'
1297 FF
1298 Notas PHP para Profissionais 20
1299 //é uma variável superglobal
1300 $GLOBALS ['amount_of_log_calls'] + = 1;
1301 echo $messsage;
1302 }
1303 Podese perguntar, por que usar o array $GLOBALS quando a palavrachave global também
pode ser usada para obter uma variável global?
1304 valor? O principal motivo é usar a palavrachave global para trazer a variável ao
escopo Você não pode reutilizar
1305 mesmo nome de variável no escopo local.
1306 FF
1307 Notas PHP para Profissionais 21
1308 Capítulo 4: Variáveis Superglobais PHP
1309 Superglobais são variáveis internas que estão sempre disponíveis em todos os escopos
1310 Várias variáveis predefinidas no PHP são "superglobais", o que significa que elas
estão disponíveis em todos os escopos ao longo de um
1311 roteiro Não há necessidade de fazer uma variável $global; para acessálos dentro de
funções ou métodos.
1312 Seção 4.1: Suberglobals explicado
1313 Introdução
1314 Simplificando, estas são variáveis que estão disponíveis em todos os escopos em seus
scripts
1315 Isso significa que não há necessidade de passálos como parâmetros em suas funções ou
armazenálos fora de um bloco de
1316 código para disponibilizálos em diferentes escopos
1317 O que é um superglobal?
1318 Se você está pensando que estes são como superheróis eles não são
1319 A partir do PHP versão 7.1.3 existem 9 variáveis superglobais Eles são os seguintes:
1320 $GLOBALS Referencia todas as variáveis disponíveis no escopo global
1321 $_SERVER Servidor e informações do ambiente de execução
1322 $_GET Variáveis HTTP GET
1323 $_POST Variáveis HTTP POST
1324 $_FILES Variáveis de upload de arquivos HTTP
1325 $_COOKIE Cookies HTTP
1326 $_SESSION Variáveis de sessão
1327 $_REQUEST Variáveis de solicitação HTTP
1328 $_ENV Variáveis de ambiente
1329 Veja a documentação
1330 Me conte mais, me conte mais
1331 Sinto muito pela referência da Grease! Ligação
1332 Tempo para alguma explicação sobre esses superheroesglobals
1333 $GLOBALS
1334 Uma matriz associativa contendo referências a todas as variáveis atualmente
definidas no escopo global
1335 do roteiro Os nomes das variáveis são as chaves da matriz.
1336 Código
1337 $myGlobal = "global"; //declara a variável fora do escopo
1338 teste de funcionamento()
1339 {
1340 $myLocal = "local"; //declara a variável dentro do escopo
1341 //ambas as variáveis são impressas
1342 var_dump ($myLocal);
1343 FF
1344 Notas PHP para Profissionais 22
1345 var_dump ($GLOBALS ["myGlobal"]);
1346 }
1347 teste(); //run function
1348 //somente $myGlobal é impresso porque $myLocal não é globalmente definido
1349 var_dump ($myLocal);
1350 var_dump ($myGlobal);
1351 Saída
1352 string 'local' (tamanho = 5)
1353 string 'global' (tamanho = 6)
1354 nulo
1355 string 'global' (tamanho = 6)
1356 No exemplo acima, $myLocal não é exibido pela segunda vez porque é declarado dentro
da função test ()
1357 e depois destruído depois que a função é fechada
1358 Tornandose global
1359 Para remediar isso, existem duas opções
1360 Opção 1: palavrachave global
1361 teste de funcionamento()
1362 {
1363 global $myLocal;
1364 $myLocal = "local";
1365 var_dump ($myLocal);
1366 var_dump ($GLOBALS ["myGlobal"]);
1367 }
1368 A palavrachave global é um prefixo de uma variável que a força a fazer parte do
escopo global
1369 Observe que você não pode atribuir um valor a uma variável na mesma instrução que a
palavrachave global Por isso, porque eu tive que
1370 atribuir um valor abaixo (É possível se você remover novas linhas e espaços, mas eu
não acho que seja puro Global
1371 $myLocal; $myLocal = "local").
1372 Opção dois: array $GLOBALS
1373 teste de funcionamento()
1374 {
1375 $GLOBALS ["myLocal"] = "local";
1376 $myLocal = $GLOBALS ["meuLocal"];
1377 var_dump ($myLocal);
1378 var_dump ($GLOBALS ["myGlobal"]);
1379 }
1380 Neste exemplo eu reatribuí $myLocal o valor de $GLOBAL ["myLocal"] desde que eu acho
mais fácil escrever um nome de variável
1381 em vez do array associativo
1382 $_SERVER
1383 $_SERVER é uma matriz contendo informações como cabeçalhos, caminhos e locais de
script As entradas em
1384 essa matriz é criada pelo servidor da web Não há garantia de que todos os servidores
da Web fornecerão
1385 estes; servidores podem omitir alguns, ou fornecer outros não listados aqui Dito
isto, um grande número destes
1386 FF
1387 Notas PHP para Profissionais 23
1388 variáveis são contabilizadas na especificação CGI /1.1, então você deve poder
esperar por elas
1389 Uma saída de exemplo disso pode ser a seguinte (executar no meu PC com Windows
usando o WAMP)
1390 C: \ wamp64 \ www \ test.php: 2:
1391 array (tamanho = 36)
1392 'HTTP_HOST' => string 'localhost' (tamanho = 9)
1393 'HTTP_CONNECTION' => string 'keepalive' (comprimento = 10)
1394 'HTTP_CACHE_CONTROL' => string 'maxage = 0' (comprimento = 9)
1395 'HTTP_UPGRADE_INSECURE_REQUESTS' => string '1' (comprimento = 1)
1396 'HTTP_USER_AGENT' => string 'Mozilla /5.0 (Windows NT 10.0; WOW64) AppleWebKit
/537.36 (KHTML,
1397 como o Gecko) Chrome /57.0.2987.133 Safari /537.36 '(comprimento = 110)
1398 'HTTP_ACCEPT' => string
1399 'texto /html, aplicativo /xhtml + xml, aplicativo /xml; q = 0,9, imagem /webp, */*;
q = 0,8' (tamanho = 74)
1400 'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate, sdch, br' (tamanho = 23)
1401 'HTTP_ACCEPT_LANGUAGE' => string 'enUS, en; q = 0,8, enGB; q = 0,6' (tamanho = 26)
1402 'HTTP_COOKIE' => string 'PHPSESSID = 0gslnvgsci371ete9hg7k9ivc6' (tamanho = 36)
1403 'PATH' => string 'C: \ Arquivos de Programas (x86) \ NVIDIA Corporation \ PhysX \
Common; C: \ Arquivos de Programas
1404 (x86) \ Intel \ Cliente iCLS \; C: \ Arquivos de Programas \ Intel \ iCLS
1405 Cliente \; C: \ ProgramData \ Oracle \ Java \ javapath; C: \ WINDOWS \ system32; C:
\ WINDOWS; C: \ WINDOWS \ System32 \ Wbem
1406 C: \ WINDOWS \ System32 \ WindowsPowerShell \ v1.0 \; E: \ Arquivos de programas \
Tecnologias ATI \ ATI.ACE \ Core
1407 Estático; E: \ Arquivos de programas \ AMD \ ATI.ACE \ CoreStatic; C: \ Arquivos de
programas (x86) \ AMD \ ATI.ACE \ Core
1408 Estático; C: \ Arquivos de programas (x86) \ ATI Technologies \ ATI.ACE \
CoreStatic; C: \ Arquivos de programas \ Intel \ Intel (R)
1409 Gerenciamento '.(comprimento = 1169)
1410 'SystemRoot' => string 'C: \ WINDOWS' (tamanho = 10)
1411 'COMSPEC' => string 'C: \ WINDOWS \ system32 \ cmd.exe' (tamanho = 27)
1412 'PATHEXT' => string '.COM; .EXE; .BAT; .CMD; .VBS; .VBE; .JS; .JSE; .WSF; .WSH;
.MSC; .PY' (comprimento = 57)
1413 'WINDIR' => string 'C: \ WINDOWS' (tamanho = 10)
1414 'SERVER_SIGNATURE' => string '<endereço> Apache /2.4.23 (Win64) Servidor PHP /7.0.10
em localhost
1415 Porta 80 </endereço> '(comprimento = 80)
1416 'SERVER_SOFTWARE' => string 'Apache /2.4.23 (Win64) PHP /7.0.10' (tamanho = 32)
1417 'SERVER_NAME' => string 'localhost' (tamanho = 9)
1418 'SERVER_ADDR' => string ':: 1' (comprimento = 3)
1419 'SERVER_PORT' => string '80' (comprimento = 2)
1420 'REMOTE_ADDR' => string ':: 1' (comprimento = 3)
1421 'DOCUMENT_ROOT' => string 'C: /wamp64 /www' (tamanho = 13)
1422 'REQUEST_SCHEME' => string 'http' (tamanho = 4)
1423 'CONTEXT_PREFIX' => string '' (comprimento = 0)
1424 'CONTEXT_DOCUMENT_ROOT' => string 'C: /wamp64 /www' (tamanho = 13)
1425 'SERVER_ADMIN' => string 'wampserver@wampserver.invalid' (comprimento = 29)
1426 'SCRIPT_FILENAME' => string 'C: /wamp64/www/test.php' (tamanho = 26)
1427 'REMOTE_PORT' => string '5359' (comprimento = 4)
1428 'GATEWAY_INTERFACE' => string 'CGI /1.1' (comprimento = 7)
1429 'SERVER_PROTOCOL' => string 'HTTP /1.1' (comprimento = 8)
1430 'REQUEST_METHOD' => string 'GET' (comprimento = 3)
1431 'QUERY_STRING' => string '' (comprimento = 0)
1432 'REQUEST_URI' => string '/test.php' (comprimento = 13)
1433 'SCRIPT_NAME' => string '/test.php' (tamanho = 13)
1434 'PHP_SELF' => string '/test.php' (comprimento = 13)
1435 'REQUEST_TIME_FLOAT' => float 1491068771.413
1436 'REQUEST_TIME' => int 1491068771
1437 Há muito para levar lá, então vou escolher alguns importantes abaixo Se você quiser
ler sobre todos eles, então
1438 consulte a seção de índices da documentação
1439 Eu poderia adicionar todos abaixo de um dia Ou alguém pode editar e adicionar uma
boa explicação deles abaixo? Sugestão, sugestão;)
1440 Para todas as explicações abaixo, assuma que o URL é http://www.example.com/index.php
1441 HTTP_HOST O endereço do host.
1442 FF
1443 Notas PHP para Profissionais 24
1444 Isso retornaria www.example.com
1445 HTTP_USER_AGENT Conteúdo do agente do usuário Esta é uma string que contém todas as
informações sobre o
1446 navegador do cliente, incluindo o sistema operacional
1447 HTTP_COOKIE Todos os cookies em uma string concatenada, com um delimitador de ponto
e vírgula
1448 SERVER_ADDR O endereço IP do servidor, do qual o script atual está sendo executado
1449 Isso retornaria 93.184.216.34
1450 PHP_SELF O nome do arquivo do script atualmente executado, relativo à raiz do
documento
1451 Isso retornaria /index.php
1452 REQUEST_TIME_FLOAT O registro de data e hora do início da solicitação, com precisão
de microssegundos Disponível desde
1453 PHP 5.4.0
1454 REQUEST_TIME O registro de data e hora do início da solicitação Disponível desde o
PHP 5.1.0.
1455 $_GET
1456 Uma matriz associativa de variáveis passadas para o script atual por meio dos
parâmetros de URL
1457 $_GET é uma matriz que contém todos os parâmetros de URL; estes são o que quer que
seja depois do? no URL.
1458 Usando http://www.example.com/index.php?myVar=myVal como exemplo Esta informação
deste URL pode ser
1459 obtido acessando neste formato $_GET ["myVar"] e o resultado disso será myVal
1460 Usando algum código para aqueles que não gostam de ler
1461 //URL = http://www.example.com/index.php?myVar=myVal
1462 echo $_GET ["myVar"] == "myVal"? "verdadeiro falso"; //retorna "true"
1463 O exemplo acima faz uso do operador ternário
1464 Isso mostra como você pode acessar o valor da URL usando o superglobal $_GET
1465 Agora outro exemplo! suspiro
1466 //URL = http://www.example.com/index.php?myVar=myVal&myVar2=myVal2
1467 echo $_GET ["myVar"]; //retorna "myVal"
1468 echo $_GET ["myVar2"]; //retorna "myVal2"
1469 É possível enviar várias variáveis por meio do URL, separandoas com um caractere e
comercial (&)
1470 Risco de segurança
1471 É muito importante não enviar informações confidenciais por meio do URL, pois elas
permanecerão no histórico do computador e
1472 ficará visível para qualquer pessoa que possa acessar esse navegador
1473 $_POST
1474 Uma matriz associativa de variáveis passadas para o script atual através do método
HTTP POST ao usar
1475 application /xwwwformurlencoded ou multipart /formdata como o HTTP ContentType na
solicitação
1476 Muito semelhante ao $_GET em que os dados são enviados de um lugar para outro
1477 Vou começar indo direto para um exemplo (Omiti o atributo de ação, pois isso enviará
as informações para
1478 a página na qual o formulário está).
1479 FF
1480 Notas PHP para Profissionais 25
1481 <form method = "POST">
1482 <input type = "text" nome = "myVar" valor = "myVal" />
1483 <input type = "submit" name = "enviar" valor = "Enviar" />
1484 </form>
1485 Acima está um formulário básico para o qual os dados podem ser enviados Em um
ambiente real, o atributo value não seria definido
1486 significando que o formulário estaria em branco Isso enviaria qualquer informação
que fosse inserida pelo usuário.
1487 echo $_POST ["myVar"]); //retorna "myVal"
1488 Risco de segurança
1489 O envio de dados via POST também não é seguro O uso de HTTPS garantirá que os dados
sejam mantidos mais seguros.
1490 $_FILES
1491 Um array associativo de itens enviados para o script atual por meio do método HTTP
POST A estrutura de
1492 essa matriz é descrita na seção de uploads do método POST
1493 Vamos começar com um formulário básico
1494 <form method = "POST" enctype = "multiparte /dados de formulário">
1495 <input type = "file" name = "myVar" />
1496 <input type = "submit" name = "Enviar" />
1497 </form>
1498 Observe que omiti o atributo action (novamente!) Além disso, eu adicionei enctype =
"multipart /formdata", isso é importante
1499 para qualquer forma que lide com uploads de arquivos
1500 //garantir que não haja um erro
1501 if ($_FILES ["myVar"] ["erro"] == UPLOAD_ERR_OK)
1502 {
1503 $folderLocation = "myFiles"; //um caminho relativo (poderia ser "path /to /file" por
exemplo)
1504 //se a pasta não existir, então faça
1505 if (! file_exists ($folderLocation)) mkdir ($pastaLocation);
1506 //move o arquivo para a pasta
1507 move_uploaded_file ($_ FILES ["myVar"] ["tmp_name"], "$folderLocation /"
1508 basename ($_ FILES ["myVar"] ["nome"]));
1509 }
1510 Isso é usado para fazer upload de um arquivo Às vezes você pode querer enviar mais
de um arquivo Existe um atributo para isso,
1511 é chamado de múltiplo
1512 Existe um atributo para praticamente qualquer coisa Eu sinto Muito
1513 Abaixo está um exemplo de um formulário que envia vários arquivos
1514 <form method = "POST" enctype = "multiparte /dados de formulário">
1515 <input type = "file" name = "myVar []" múltiplo = "múltiplo" />
1516 <input type = "submit" name = "Enviar" />
1517 </form>
1518 Observe as alterações feitas aqui; Existem apenas alguns.
1519 O nome da entrada possui colchetes Isto é porque agora é uma matriz de arquivos e
por isso estamos dizendo a forma
1520 FF
1521 Notas PHP para Profissionais 26
1522 para fazer uma matriz dos arquivos selecionados Omitir os colchetes resultará no
último arquivo sendo definido
1523 para $_FILES ["myVar"]
1524 O atributo multiple = "multiple" Isso apenas informa ao navegador que os usuários
podem selecionar mais de um arquivo.
1525 $total = isset ($_ FILES ["myVar"])? count ($_ FILES ["myVar"] ["nome"]): 0; //conta
quantos arquivos
1526 foram enviados
1527 //iterar sobre cada um dos arquivos
1528 para ($i = 0; $i <$total; $i ++)
1529 {
1530 //não há erro
1531 if ($_FILES ["myVar"] ["erro"] [$i] == UPLOAD_ERR_OK)
1532 {
1533 $folderLocation = "myFiles"; //um caminho relativo (poderia ser "path /to /file" por
exemplo)
1534 //se a pasta não existir, então faça
1535 if (! file_exists ($folderLocation)) mkdir ($pastaLocation);
1536 //move o arquivo para a pasta
1537 move_uploaded_file ($_ FILES ["myVar"] ["nome_tcmp"] [$i], "$folderLocation /"
1538 basename ($_ FILES ["myVar"] ["nome"] [$i]));
1539 }
1540 //else reporta o erro
1541 Outro switch ($_FILES ["myVar"] ["error"] [$i])
1542 {
1543 case UPLOAD_ERR_INI_SIZE:
1544 echo "Valor: 1; o arquivo enviado excede a diretiva upload_max_filesize em
1545 php.ini ";
1546 pausa;
1547 case UPLOAD_ERR_FORM_SIZE:
1548 echo "Valor: 2; o arquivo enviado excede a diretiva MAX_FILE_SIZE que estava
1549 especificado no formulário HTML ";
1550 pausa;
1551 caso UPLOAD_ERR_PARTIAL:
1552 echo "Valor: 3; o arquivo enviado foi apenas parcialmente carregado.";
1553 pausa;
1554 caso UPLOAD_ERR_NO_FILE:
1555 echo "Valor: 4; Nenhum arquivo foi carregado.";
1556 pausa;
1557 caso UPLOAD_ERR_NO_TMP_DIR:
1558 echo "Valor: 6; Faltando uma pasta temporária Introduzido no PHP 5.0.3.";
1559 pausa;
1560 caso UPLOAD_ERR_CANT_WRITE:
1561 echo "Valor: 7; Falha ao gravar arquivo em disco Introduzido no PHP 5.1.0.";
1562 pausa;
1563 caso UPLOAD_ERR_EXTENSION:
1564 echo "Valor: 8; Uma extensão do PHP parou o upload do arquivo O PHP não fornece uma
maneira de
1565 verificar qual extensão causou o upload do arquivo para parar; Examinando a lista de
extensões carregadas
1566 com phpinfo () pode ajudar Introduzido no PHP 5.2.0 ";
1567 pausa;
1568 padrão:
1569 echo "Ocorreu um erro desconhecido.";
1570 pausa;
1571 }
1572 }
1573 Este é um exemplo muito simples e não lida com problemas como extensões de arquivos
que não são permitidos ou arquivos
1574 nomeado com código PHP (como um equivalente PHP de uma injeção SQL) Veja a
documentação.
1575 O primeiro processo é verificar se há algum arquivo e, em caso afirmativo, definir o
número total deles para $total.
1576 FF
1577 Notas PHP para Profissionais 27
1578 O uso do loop for permite uma iteração da matriz $_FILES e o acesso a cada item, um
de cada vez Se esse arquivo não
1579 encontrar um problema, em seguida, a declaração if é verdadeira e o código do upload
de arquivo único é executado
1580 Se um problema for encontrado, o bloco do comutador é executado e um erro é
apresentado de acordo com o erro
1581 para esse upload específico
1582 $_COOKIE
1583 Um array associativo de variáveis passadas para o script atual via HTTP Cookies
1584 Cookies são variáveis que contêm dados e são armazenados no computador do cliente
1585 Ao contrário das superglobais acima mencionadas, os cookies devem ser criados com
uma função (e não atribuir um valor)
1586 A convenção está abaixo
1587 setcookie ("myVar", "myVal", tempo () + 3600);
1588 Neste exemplo, um nome é especificado para o cookie (neste exemplo é "myVar"), um
valor é dado (neste exemplo é
1589 "myVal", mas uma variável pode ser passada para atribuir seu valor ao cookie) e, em
seguida, é dado um tempo de expiração (neste
1590 exemplo, é uma hora desde 3600 segundos é um minuto)
1591 Apesar da convenção para criar um cookie sendo diferente, ele é acessado da mesma
maneira que os outros
1592 echo $_COOKIE ["myVar"]; //retorna "myVal"
1593 Para destruir um cookie, o setcookie deve ser chamado novamente, mas o tempo de
expiração é definido para qualquer momento no passado Vejo
1594 abaixo
1595 setcookie ("myVar", "", hora () 1);
1596 var_dump ($_ COOKIE ["myVar"]); //retorna nulo
1597 Isto irá remover os cookies e removêlos do computador do cliente
1598 $_SESSION
1599 Um array associativo contendo variáveis de sessão disponíveis para o script atual
Veja as funções da sessão
1600 documentação para obter mais informações sobre como isso é usado
1601 As sessões são muito parecidas com cookies, exceto pelo lado do servidor
1602 Para usar as sessões, você deve incluir session_start () na parte superior de seus
scripts para permitir que as sessões sejam utilizadas
1603 Definir uma variável de sessão é o mesmo que definir qualquer outra variável Veja o
exemplo abaixo.
1604 $_SESSION ["myVar"] = "myVal";
1605 Ao iniciar uma sessão, um ID aleatório é definido como um cookie e chamado
"PHPSESSID" e conterá o ID da sessão para
1606 essa sessão atual Isso pode ser acessado chamando a função session_id ().
1607 É possível destruir variáveis de sessão usando a função unset (de forma que unset
($_ SESSION ["myVar"])
1608 destruir essa variável)
1609 A alternativa é chamar session_destory () Isso destruirá a sessão inteira, o que
significa que todas as variáveis da sessão
1610 não existirá mais.
1611 FF
1612 Notas PHP para Profissionais 28
1613 $_REQUEST
1614 Uma matriz associativa que, por padrão, contém o conteúdo de $_GET, $_POST e $_COOKIE
1615 Como a documentação do PHP afirma, isso é apenas um agrupamento de $_GET, $_POST e
$_COOKIE, tudo em uma variável
1616 Como é possível que todos os três arrays tenham um índice com o mesmo nome, existe
uma configuração no
1617 arquivo php.ini chamado request_order que pode especificar qual dos três tem
precedência
1618 Por exemplo, se foi definido como "GPC", o valor de $_COOKIE será usado, pois é lido
da esquerda para a direita, significando
1619 o $_REQUEST irá definir seu valor para $_GET, depois para $_POST, e então para
$_COOKIE e uma vez que $_COOKIE é o último que é o valor
1620 isso está em $_REQUEST
1621 Veja esta questão
1622 $_ENV
1623 Uma matriz associativa de variáveis passadas para o script atual através do método
do ambiente
1624 Essas variáveis são importadas para o namespace global do PHP a partir do ambiente
sob o qual o PHP
1625 analisador está em execução Muitos são fornecidos pelo shell sob o qual o PHP está
sendo executado e sistemas diferentes são
1626 provavelmente executando diferentes tipos de conchas, uma lista definitiva é
impossível Por favor, veja o seu escudo
1627 documentação para uma lista de variáveis de ambiente definidas
1628 Outras variáveis de ambiente incluem as variáveis CGI, colocadas lá
independentemente de o PHP estar rodando
1629 como um módulo de servidor ou processador CGI
1630 Qualquer coisa armazenada em $_ENV é do ambiente do qual o PHP está sendo executado
1631 $_ENV só é preenchido se o php.ini permitir
1632 Veja esta resposta para mais informações sobre o porquê $_ENV não é preenchido
1633 Seção 4.2: PHP5 SuperGlobals
1634 Abaixo estão os SuperGlobals PHP5
1635 $GLOBALS
1636 $_REQUEST
1637 $_GET
1638 $_POST
1639 $_FILES
1640 $_SERVER
1641 $_ENV
1642 $_COOKIE
1643 $_SESSION
1644 $GLOBALS: Esta Variável SuperGlobal é usada para acessar variáveis globais
1645 <?php
1646 $a = 10;
1647 função foo () {
1648 echo $GLOBALS ['a'];
1649 }
1650 //Que irá imprimir 10 Global Variable a
1651 FF
1652 Notas PHP para Profissionais 29
1653 ?>
1654 $_REQUEST: Esta Variável SuperGlobal é usada para coletar dados enviados por um
formulário HTML
1655 <?php
1656 if (isset ($_ REQUEST ['usuário'])) {
1657 echo $_REQUEST ['user'];
1658 }
1659 //Isso imprimirá o valor do campo HTML com nome = usuário enviado usando POST e /ou
GET MEthod
1660 ?>
1661 $_GET: essa variável superglobal é usada para coletar dados enviados pelo formulário
HTML com o método get
1662 <?php
1663 if (isset ($_ GET ['nome de usuário'])) {
1664 echo $_GET ['nome de usuário'];
1665 }
1666 //Isso imprimirá o valor do campo HTML com nome de usuário enviado usando o método
GET
1667 ?>
1668 $_POST: essa variável superglobal é usada para coletar dados enviados pelo
formulário HTML com o método post
1669 <?php
1670 if (isset ($_ POST ['nome de usuário'])) {
1671 echo $_POST ['username'];
1672 }
1673 //Isso imprimirá o valor do campo HTML com nome de usuário enviado usando o método
POST
1674 ?>
1675 $_FILES: Esta Variável SuperGlobal contém as informações dos arquivos enviados por
meio do método HTTP Post
1676 <?php
1677 if ($_ FILES ['imagem']) {
1678 echo "<pre>";
1679 print_r ($_ FILES ['imagem']);
1680 eco "</pre>";
1681 }
1682 /**
1683 Isso imprimirá os detalhes do arquivo com a imagem de nome enviada por meio de um
formulário com method = 'post e com
1684 enctype = 'multipart /formdata'
1685 Detalhes inclui nome do arquivo, tipo de arquivo, local do arquivo temporário,
código de erro (se houver algum erro
1686 ocorreu durante o upload do arquivo) e tamanho do arquivo em Bytes
1687 Por exemplo
1688 Matriz
1689 (
1690 [foto] => Matriz
1691 (
1692 [0] => Matriz
1693 (
1694 [name] => 400.png
1695 [type] => imagem /png
1696 [nome_tmp] => /tmp /php5Wx0aJ
1697 [error] => 0
1698 [tamanho] => 15726
1699 )
1700 )
1701 )
1702 FF
1703 Notas PHP para Profissionais 30
1704 */
1705 ?>
1706 $_SERVER: Esta Variável SuperGlobal contém informações sobre Scripts, Cabeçalhos
HTTP e Caminhos do Servidor
1707 <?php
1708 echo "<pre>";
1709 print_r ($_ SERVER);
1710 eco "</pre>";
1711 /**
1712 Vai imprimir os seguintes detalhes
1713 no meu XAMPP local
1714 Matriz
1715 (
1716 [MIBDIRS] => C: /xampp /php /extras /mibs
1717 [MYSQL_HOME] => \ xampp \ mysql \ bin
1718 [OPENSSL_CONF] => C: /xampp/apache/bin/openssl.cnf
1719 [PHP_PEAR_SYSCONF_DIR] => \ xampp \ php
1720 [PHPRC] => \ xampp \ php
1721 [TMP] => \ xampp \ tmp
1722 [HTTP_HOST] => localhost
1723 [HTTP_CONNECTION] => manter vivo
1724 [HTTP_CACHE_CONTROL] => maxage = 0
1725 [HTTP_UPGRADE_INSECURE_REQUESTS] => 1
1726 [HTTP_USER_AGENT] => Mozilla /5.0 (Windows NT 6.1; WOW64) AppleWebKit /537.36
(KHTML, como o Gecko)
1727 Chrome /52.0.2743.82 Safari /537.36
1728 [HTTP_ACCEPT] => texto /html, aplicativo /xhtml + xml, aplicativo /xml; q = 0,9,
imagem /webp, *; q = 0,8
1729 [HTTP_ACCEPT_ENCODING] => gzip, deflate, sdch
1730 [HTTP_ACCEPT_LANGUAGE] => enUS, en; q = 0,8
1731 [PATH] => C: \ xampp \ php; C: \ ProgramData \ ComposerSetup \ bin;
1732 [SystemRoot] => C: \ Windows
1733 [COMSPEC] => C: \ Windows \ system32 \ cmd.exe
1734 [PATHEXT] => .COM; .EXE; .BAT; .CMD; .VBS; .VBE; .JS; .JSE; .WSF; .WSH; .MSC
1735 [WINDIR] => C: \ Windows
1736 [SERVER_SIGNATURE] => Apache /2.4.16 (Win32) Servidor OpenSSL /1.0.1p PHP /5.6.12 no
localhost Porta 80
1737 [SERVER_SOFTWARE] => Apache /2.4.16 (Win32) OpenSSL /1.0.1p PHP /5.6.12
1738 [SERVER_NAME] => localhost
1739 [SERVER_ADDR] => :: 1
1740 [SERVER_PORT] => 80
1741 [REMOTE_ADDR] => :: 1
1742 [DOCUMENT_ROOT] => C: /xampp /htdocs
1743 [REQUEST_SCHEME] => http
1744 [CONTEXT_PREFIX] =>
1745 [CONTEXT_DOCUMENT_ROOT] => C: /xampp /htdocs
1746 [SERVER_ADMIN] => postmaster @ localhost
1747 [SCRIPT_FILENAME] => C: /xampp/htdocs/abcd.php
1748 [REMOTE_PORT] => 63822
1749 [GATEWAY_INTERFACE] => CGI /1.1
1750 [SERVER_PROTOCOL] => HTTP /1.1
1751 [REQUEST_METHOD] => GET
1752 [QUERY_STRING] =>
1753 [REQUEST_URI] => /abcd.php
1754 [SCRIPT_NAME] => /abcd.php
1755 [PHP_SELF] => /abcd.php
1756 [REQUEST_TIME_FLOAT] => 1469374173.88
1757 [REQUEST_TIME] => 1469374173
1758 )
1759 */
1760 ?>
1761 $_ENV: Detalhes da Variável de Ambiente da Shell SuperGlobal Variável sob a qual o
PHP está sendo executado.
1762 FF
1763 Notas PHP para Profissionais 31
1764 $_COOKIE: Esta Variável SuperGlobal é usada para recuperar o valor do Cookie com uma
determinada Chave
1765 <?php
1766 $cookie_name = "data";
1767 $cookie_value = "Barra de Foo";
1768 setcookie ($cookie_name, $cookie_value, time () + (86400 * 30), "/"); //86400 = 1 dia
1769 if (! isset ($_ COOKIE [$cookie_name])) {
1770 echo "Cookie nomeado '" $cookie_name "'não está definido!";
1771 }
1772 outro {
1773 echo "Cookie '" $cookie_name "'está pronto! <br>";
1774 echo "O valor é:" $_COOKIE [$cookie_name];
1775 }
1776 /**
1777 Saída
1778 Cookie 'data' está definido!
1779 O valor é: Foo Bar
1780 */
1781 ?>
1782 $_SESSION: Esta Variável SuperGlobal é usada para definir e recuperar o valor da
sessão, que é armazenado no servidor
1783 <?php
1784 //Iniciar a sessão
1785 session_start ();
1786 /**
1787 Definindo as variáveis de sessão
1788 que pode ser acessado em diferentes
1789 páginas no servidor salvar
1790 */
1791 $_SESSION ["username"] = "John Doe";
1792 $_SESSION ["user_token"] = "d5f1df5b4dfb8b8d5f";
1793 echo "A sessão é salva com sucesso";
1794 /**
1795 Saída
1796 Sessão é salva com sucesso
1797 */
1798 ?>
1799 FF
1800 Notas PHP para Profissionais 32
1801 Capítulo 5: Produzindo o valor de um
1802 Variável
1803 Para construir um programa PHP dinâmico e interativo, é útil para as variáveis de
saída e seus valores A linguagem PHP
1804 permite vários métodos de saída de valor Este tópico aborda os métodos padrão de
impressão de um valor em PHP e
1805 onde esses métodos podem ser usados
1806 Seção 5.1: eco e impressão
1807 eco e impressão são construções de linguagem, não funções Isso significa que eles
não exigem parênteses ao redor do
1808 argumento como uma função faz (embora um sempre pode adicionar parênteses em torno
de quase qualquer expressão PHP e
1809 assim, echo ("teste") também não causará nenhum dano Eles geram a representação de
string de uma variável, constante ou
1810 expressão Eles não podem ser usados para imprimir matrizes ou objetos.
1811 Atribuir a string Joel à variável $name
1812 $name = "Joel";
1813 Saída do valor de $name usando echo e print
1814 echo $name; #> Joel
1815 imprima $name; #> Joel
1816 Parênteses não são necessários, mas podem ser usados
1817 echo ($name); #> Joel
1818 print ($name); #> Joel
1819 Usando vários parâmetros (apenas eco)
1820 echo $name, "Smith"; # JoelSmith
1821 echo ($name, "", "Smith"); Joel Smith
1822 print, ao contrário de echo, é uma expressão (retorna 1) e, portanto, pode ser usada
em mais lugares:
1823 print ("hey") && print ("") && print ("você"); #> you11
1824 O acima é equivalente a:
1825 print ("hey" && (print ("" && print "você"))); #> you11
1826 Notação de taquigrafia para eco
1827 Quando fora das tags PHP, uma notação abreviada para eco está disponível por padrão,
usando <? = Para iniciar a saída e?> Para
1828 acabar com isso Por exemplo:
1829 <p> <? = $variable?> </p>
1830 <p> <? = "Isto também é PHP"?> </p>
1831 Note que não há finalização; Isso funciona porque a tag do PHP de fechamento atua
como o terminador do single
1832 FF
1833 Notas PHP para Profissionais 33
1834 declaração Portanto, é convencional omitir o pontoevírgula nesta notação abreviada.
1835 Prioridade da impressão
1836 Embora a impressão seja de construção de linguagem, ela tem prioridade como operador
Coloque entre = + = = * = ** = /= =% =
1837 & = ee operadores e saiu da associação Exemplo:
1838 eco '1' imprima '2' + 3; //saída 511
1839 Mesmo exemplo com colchetes:
1840 eco '1' impressão ('2' + 3); //saída 511
1841 Diferenças entre o eco e a impressão
1842 Em suma, existem duas diferenças principais:
1843 imprimir só leva um parâmetro, enquanto o eco pode ter vários parâmetros
1844 print retorna um valor, então pode ser usado como uma expressão
1845 Seção 5.2: Gerando uma visão estruturada de matrizes e
1846 objetos
1847 print_r () Saída de matrizes e objetos para depuração
1848 O print_r mostrará um formato legível por humanos de um array ou objeto
1849 Você pode ter uma variável que seja uma matriz ou objeto Tentando dar saída com um
eco, o erro será lançado:
1850 Aviso: Array para conversão de string Você pode, em vez disso, usar a função print_r
para despejar um arquivo legível
1851 formato desta variável
1852 Você pode passar true como o segundo parâmetro para retornar o conteúdo como uma
string
1853 $myobject = novo stdClass ();
1854 $myobject> myvalue = 'Olá mundo';
1855 $myarray = ["Olá", "Mundo"];
1856 $mystring = "Olá mundo";
1857 $myint = 42;
1858 //Usando o print_r podemos ver os dados que a matriz contém
1859 print_r ($myobject);
1860 print_r ($myarray);
1861 print_r ($mystring);
1862 print_r ($myint);
1863 Isso gera o seguinte:
1864 Objeto stdClass
1865 (
1866 [myvalue] => Olá, mundo
1867 )
1868 Matriz
1869 (
1870 [0] => Olá
1871 [1] => mundo
1872 )
1873 FF
1874 Notas PHP para Profissionais 34
1875 Olá Mundo
1876 42
1877 Além disso, a saída do print_r pode ser capturada como uma string, em vez de
simplesmente ser reproduzida Por exemplo, o seguinte
1878 código irá despejar a versão formatada de $myarray em uma nova variável:
1879 $formatted_array = print_r ($myarray, true);
1880 Note que se você está vendo a saída do PHP em um navegador, e ele é interpretado
como HTML, então as quebras de linha serão
1881 não será mostrado e a saída será muito menos legível, a menos que você faça algo como
1882 eco '<pre>' print_r ($myarray, true) '</pre>';
1883 Abrir o códigofonte de uma página também formatará sua variável da mesma maneira sem
o uso da
1884 tag <pre>
1885 Alternativamente, você pode dizer ao navegador que o que você está produzindo é
texto simples, e não HTML:
1886 header ('Tipo de Conteúdo: text /plain; charset = utf8');
1887 print_r ($myarray);
1888 var_dump () Exibe informações de depuração legíveis por humanos sobre o conteúdo do
(s) argumento (s), incluindo seus
1889 tipo e valor
1890 A saída é mais detalhada em comparação com print_r, porque ela também mostra o tipo
da variável junto com sua
1891 valor e outras informações como IDs de objeto, tamanhos de matriz, comprimentos de
string, marcadores de referência, etc
1892 Você pode usar var_dump para gerar uma versão mais detalhada para depuração
1893 var_dump ($myobject, $myarray, $mystring, $myint);
1894 A saída é mais detalhada:
1895 objeto (stdClass) # 12 (1) {
1896 ["myvalue"] =>
1897 string (11) "Olá, mundo"
1898 }
1899 array (2) {
1900 [0] =>
1901 string (5) "Olá"
1902 [1] =>
1903 string (5) "mundo"
1904 }
1905 string (11) "Olá, mundo"
1906 int (42)
1907 Nota: Se você estiver usando xDebug em seu ambiente de desenvolvimento, a saída de
var_dump será limitada /truncada por
1908 padrão Veja a documentação oficial para mais informações sobre as opções para mudar
isso.
1909 var_export () Saída de código PHP válido
1910 var_export () copia uma representação PHP parseable do item.
1911 FF
1912 Notas PHP para Profissionais 35
1913 Você pode passar true como o segundo parâmetro para retornar o conteúdo em uma
variável
1914 var_export ($myarray);
1915 var_export ($mystring);
1916 var_export ($myint);
1917 A saída é um código PHP válido:
1918 array (
1919 0 => 'Olá',
1920 1 => 'mundo',
1921 )
1922 'Olá Mundo'
1923 42
1924 Para colocar o conteúdo em uma variável, você pode fazer isso:
1925 $array_export = var_export ($myarray, true);
1926 $string_export = var_export ($mystring, true);
1927 $int_export = var_export ($myint, 1); //qualquer valor `Truthy`
1928 Depois disso, você pode imprimilo assim:
1929 printf ('$myarray =% s;% s', $array_export, PHP_EOL);
1930 printf ('$mystring =% s;% s', $string_export, PHP_EOL);
1931 printf ('$myint =% s;% s', $int_export, PHP_EOL);
1932 Isso produzirá a seguinte saída:
1933 $myarray = array (
1934 0 => 'Olá',
1935 1 => 'mundo',
1936 );
1937 $mystring = 'Olá mundo';
1938 $myint = 42;
1939 Seção 5.3: Concatenação de cordas com eco
1940 Você pode usar a concatenação para unir strings "de ponta a ponta" durante a saída
(com eco ou impressão, por exemplo)
1941 Você pode concatenar variáveis usando a (ponto /ponto).
1942 //String variable
1943 $name = 'Joel';
1944 //Concatene várias strings (3 neste exemplo) em uma e faça o eco uma vez feito
1945 //12 3 Três itens de string individuais
1946 echo '<p> Olá' $name ', Bom ver você </P>';
1947 // operadores de concatenação
1948 #> "<p> Olá Joel, prazer em vêlo </p>"
1949 Semelhante à concatenação, o echo (quando usado sem parênteses) pode ser usado para
combinar strings e variáveis
1950 juntos (junto com outras expressões arbitrárias) usando uma vírgula (,)
1951 $itemCount = 1;
1952 FF
1953 Notas PHP para Profissionais 36
1954 echo 'Você pediu', $itemCount, 'item', $itemCount === 1? '': 's';
1955 // Observe as vírgulas
1956 #> "Você encomendou 1 item"
1957 Concatenação de strings vs passando múltiplos argumentos para ecoar
1958 Passar vários argumentos para o comando echo é mais vantajoso que a concatenação de
strings em alguns
1959 circunstâncias Os argumentos são gravados na saída na mesma ordem em que são passados.
1960 echo "O total é:", $x + $y;
1961 O problema com a concatenação é que o período tem precedência na expressão Se
concatenado, o
1962 A expressão acima precisa de parênteses extras para o comportamento correto A
precedência do período afeta ternário
1963 operadores também
1964 echo "O total é:" ($x + $y);
1965 Seção 5.4: printf vs sprintf
1966 printf irá imprimir uma string formatada usando placeholders
1967 O sprintf retornará a string formatada
1968 $name = 'Jeff';
1969 //O `% s` diz ao PHP para esperar uma string
1970 //`% s` é substituído por.
1971 printf ("Olá% s, como está indo?", $name);
1972 #> Olá Jeff, como vai?
1973 //Em vez de gerar diretamente, coloqueo em uma variável ($greeting)
1974 $greeting = sprintf ("Olá% s, como está indo?", $name);
1975 echo $greeting;
1976 #> Olá Jeff, como vai?
1977 Também é possível formatar um número com estas duas funções Isso pode ser usado para
formatar um valor decimal usado para
1978 representa dinheiro para que tenha sempre dois dígitos decimais
1979 $money = 25,2;
1980 printf ('% 01.2f', $money);
1981 # 25,20
1982 As duas funções vprintf e vsprintf operam como printf e sprintf, mas aceitam uma
string de formato e uma matriz de
1983 valores, em vez de variáveis individuais
1984 Seção 5.5: Saída de inteiros grandes
1985 Em sistemas de 32 bits, inteiros maiores que PHP_INT_MAX são automaticamente
convertidos para float Emitindo estes como
1986 valores inteiros (ou seja, notação não científica) podem ser feitos com printf,
usando a representação float, como ilustrado
1987 abaixo:
1988 foreach ([1, 2, 3, 4, 5, 6, 9, 12] como $p) {
1989 $i = pow (1024, $p);
1990 printf ("pow (1024,% d)> (% 7s)% 20s% 38.0F", $p, gettype ($i), $i, $i);
1991 FF
1992 Notas PHP para Profissionais 37
1993 echo "", $i, "\ n";
1994 }
1995 //saídas:
1996 pow (1024, 1) inteiro 1024 1024 1024
1997 pow (1024, 2) inteiro 1048576 1048576 1048576
1998 pow (1024, 3), inteiro 1073741824 1073741824 1073741824
1999 pow (1024, 4) duplo 1099511627776 1099511627776 1099511627776
2000 pow (1024, 5) duplo 1.1258999068426E + 15 1125899906842624
2001 1,1258999068426E + 15
2002 pow (1024, 6) duplo 1,1529215046068E + 18 1152921504606846976
2003 1,1529215046068E + 18
2004 pow (1024, 9) dobre 1.2379400392854E + 27 1237940039285380274899124224
2005 1.2379400392854E + 27
2006 pow (1024, 12) double 1.3292279957849E + 36 1329227995784915872903807060280344576
2007 1,3292279957849E + 36
2008 Nota: tenha em atenção a precisão da flutuação, que não é infinita!
2009 Enquanto isso parece bom, neste exemplo inventado os números podem ser representados
como um número binário, uma vez que
2010 são todos os poderes de 1024 (e, portanto, 2) Veja por exemplo:
2011 $n = pow (10, 27);
2012 printf ("% s% .0F \ n", $n, $n);
2013 //1.0E + 27 1000000000000000013287555072
2014 Seção 5.6: Saída de uma matriz multidimensional com índice e
2015 valor e imprimir na mesa
2016 Matriz
2017 (
2018 [0] => Matriz
2019 (
2020 [id] => 13
2021 [category_id] => 7
2022 [name] => Saindo de Liverpool
2023 [descrição] => Saindo De Liverpool
2024 [preço] => 1,00
2025 [virtual] => 1
2026 [ativo] => 1
2027 [sort_order] => 13
2028 [criado] => 20070624 14:08:03
2029 [modificado] => 20070624 14:08:03
2030 [imagem] => NENHUM
2031 )
2032 [1] => Matriz
2033 (
2034 [id] => 16
2035 [category_id] => 7
2036 [name] => Submarino Amarelo
2037 [descrição] => Submarino Amarelo
2038 [preço] => 1,00
2039 [virtual] => 1
2040 [ativo] => 1
2041 [sort_order] => 16
2042 [criado] => 20070624 14:10:02
2043 [modificado] => 20070624 14:10:02
2044 FF
2045 Notas PHP para Profissionais 38
2046 [imagem] => NENHUM
2047 )
2048 )
2049 Matriz Multidimensional de Saída com índice e valor na tabela
2050 <table>
2051 <?php
2052 foreach ($produtos como $chave => $valor) {
2053 foreach ($value como $k => $v) {
2054 echo "<tr>";
2055 echo "<td> $k </td>"; //Obter índice.
2056 echo "<td> $v </td>"; //Obter valor.
2057 echo "</tr>";
2058 }
2059 }
2060 ?>
2061 </table>
2062 FF
2063 Notas PHP para Profissionais 39
2064 Capítulo 6: Constantes
2065 Seção 6.1: Definindo constantes
2066 As constantes são criadas usando a instrução const ou a função define A convenção é
usar o UPPERCASE
2067 letras para nomes constantes
2068 Definir constante usando valores explícitos
2069 const PI = 3,14; //float
2070 define ("EARTH_IS_FLAT", false); //boleano
2071 const "DESCONHECIDO" = nulo; //nulo
2072 define ("APP_ENV", "dev"); //corda
2073 const MAX_SESSION_TIME = 60 * 60; //integer, usando expressões (escalares) está ok
2074 const APP_LANGUAGES = ["de", "en"]; //arrays
2075 define ("BETTER_APP_LANGUAGES", ["lu", "de"]); //arrays
2076 Definir constante usando outra constante
2077 se você tiver uma constante, você pode definir outra baseada nela:
2078 const TAU = PI * 2;
2079 define ("EARTH_IS_ROUND",! EARTH_IS_FLAT);
2080 define ("MORE_UNKNOWN", DESCONHECIDO);
2081 define ("APP_ENV_UPPERCASE", strtoupper (APP_ENV)); //manipulação de string também é
ok
2082 //o exemplo acima (uma chamada de função) não funciona com const:
2083 //const TIME = time (); # falha com um erro fatal! Não é uma expressão escalar
constante
2084 define ("MAX_SESSION_TIME_IN_MINUTES", MAX_SESSION_TIME /60);
2085 const APP_FUTURE_LANGUAGES = [1 => "es"] + APP_LANGUAGES; //manipulações de array
2086 define ("APP_BETTER_FUTURE_LANGUAGES", array_merge (["fr"], APP_BETTER_LANGUAGES));
2087 Constantes reservadas
2088 Alguns nomes constantes são reservados pelo PHP e não podem ser redefinidos Todos
esses exemplos falharão:
2089 define ("true", false); //constante interna
2090 define ("false", true); //constante interna
2091 define ("CURLOPT_AUTOREFERER", "alguma coisa"); //falhará se a extensão de curl
estiver carregada
2092 E um aviso será emitido:
2093 Constante .já definido em .
2094 Condicional define
2095 Se você tem vários arquivos onde você pode definir a mesma variável (por exemplo,
sua configuração principal, então sua
2096 config), em seguida, a sintaxe seguinte pode ajudar a evitar conflitos:
2097 definido ("PI") || define ("PI", 3.1415); //"define PI se ainda não está definido"
2098 const vs define
2099 define é uma expressão de tempo de execução enquanto const é um tempo de compilação.
2100 FF
2101 Notas PHP para Profissionais 40
2102 Assim, definir permite valores dinâmicos (isto é, chamadas de função, variáveis,
etc.) e até mesmo nomes dinâmicos e condicionais
2103 definição No entanto, ele está sempre definindo em relação ao namespace raiz.
2104 const é estático (como em permite apenas operações com outras constantes, escalares
ou arrays, e apenas um conjunto restrito deles,
2105 as chamadas expressões escalares constantes, isto é, operadores aritméticos, lógicos
e de comparação, bem como
2106 desreferência), mas são automaticamente namespaces prefixados com o namespace ativo
no momento
2107 const apenas suporta outras constantes e escalares como valores e nenhuma operação
2108 Seção 6.2: Constantes de Classe
2109 Constantes podem ser definidas dentro de classes usando uma palavrachave const
2110 class Foo {
2111 const BAR_TYPE = "bar";
2112 //referência de dentro da classe usando self ::
2113 Função pública myMethod () {
2114 return self :: BAR_TYPE;
2115 }
2116 }
2117 //referencia de fora da classe usando <ClassName> ::
2118 eco Foo :: BAR_TYPE;
2119 Isso é útil para armazenar tipos de itens
2120 <?php
2121 class Logger {
2122 const LEVEL_INFO = 1;
2123 const LEVEL_WARNING = 2;
2124 const LEVEL_ERROR = 3;
2125 //podemos até atribuir a constante como um valor padrão
2126 log de função pública ($message, $level = self :: LEVEL_INFO) {
2127 echo "Nível de mensagem" nível $ ":" $message;
2128 }
2129 }
2130 $logger = new Logger ();
2131 $logger> log ("Info"); //Usando o valor padrão
2132 $logger> log ("Aviso", $logger :: LEVEL_WARNING); //Usando var
2133 $logger> log ("Erro", Logger :: LEVEL_ERROR); //usando a classe
2134 Seção 6.3: Verificando se a constante está definida
2135 Cheque simples
2136 Para verificar se a constante está definida, use a função definida Note que esta
função não se preocupa com a constante
2137 valor, só importa se a constante existe ou não Mesmo que o valor da constante seja
nulo ou falso, a função será
2138 ainda retorna verdadeiro
2139 <?php
2140 define ("BOM", falso);
2141 if (defined ("GOOD")) {
2142 FF
2143 Notas PHP para Profissionais 41
2144 print "GOOD está definido"; //imprime "GOOD is defined"
2145 if (BOM) {
2146 print "BOM é verdade"; //não imprime nada, pois GOOD é falso
2147 }
2148 }
2149 if (! defined ("AWESOME")) {
2150 define ("AWESOME", true); //awesome não foi definido Agora nós definimos
2151 }
2152 Observe que a constante se torna "visível" em seu código somente após a linha em que
você a definiu:
2153 <?php
2154 if (defined ("GOOD")) {
2155 print "GOOD está definido"; //não imprime nada, o GOOD ainda não está definido.
2156 }
2157 define ("BOM", falso);
2158 if (defined ("GOOD")) {
2159 print "GOOD está definido"; //imprime "GOOD is defined"
2160 }
2161 Obtendo todas as constantes definidas
2162 Para obter todas as constantes definidas, incluindo aquelas criadas pelo PHP, use a
função get_defined_constants:
2163 <?php
2164 $constantes = get_defined_constants ();
2165 var_dump ($constantes); //lista bastante grande
2166 Para obter apenas as constantes definidas pelo seu aplicativo, chame a função no
início e no final do seu
2167 script (normalmente após o processo de bootstrap):
2168 <?php
2169 $constantes = get_defined_constants ();
2170 define ("OLÁ", "olá");
2171 define ("WORLD", "mundo");
2172 $new_constants = get_defined_constants ();
2173 $myconstants = array_diff_assoc ($new_constants, $constantes);
2174 var_export ($myconstants);
2175 /*
2176 Saída:
2177 array (
2178 'OLÁ!' => 'Olá',
2179 'WORLD' => 'mundo',
2180 )
2181 */
2182 Às vezes é útil para depurar
2183 FF
2184 Notas PHP para Profissionais 42
2185 Seção 6.4: Usando constantes
2186 Para usar a constante simplesmente use seu nome:
2187 if (EARTH_IS_FLAT) {
2188 print "Terra é plana";
2189 }
2190 imprime o APP_ENV_UPPERCASE;
2191 ou se você não souber o nome da constante antecipadamente, use a função constante:
2192 //este código é equivalente ao código acima
2193 $const1 = "EARTH_IS_FLAT";
2194 $const2 = "APP_ENV_UPPERCASE";
2195 if (constante ($const1)) {
2196 print "Terra é plana";
2197 }
2198 constante de impressão ($const2);
2199 Seção 6.5: Matrizes Constantes
2200 Os arrays podem ser usados como constantes simples e constantes de classe da versão
PHP 5.6 em diante:
2201 Exemplo constante de classe
2202 classe de resposta {
2203 const C = [2,4];
2204 }
2205 Resposta de impressão :: C [1] Resposta :: C [0]; //42
2206 Exemplo constante simples
2207 const ANSWER = [2,4];
2208 print RESPOSTA [1] RESPOSTA [0]; //42
2209 Também da versão PHP 7.0 esta funcionalidade foi portada para a função define para
constantes simples
2210 define ('VALORES', [2, 3]);
2211 define ('MY_ARRAY', [
2212 1,
2213 VALORES
2214 ]);
2215 print MY_ARRAY [1] [1]; //3
2216 FF
2217 Notas PHP para Profissionais 43
2218 Capítulo 7: Constantes Mágicas
2219 Seção 7.1: Diferença entre __FUNCTION__ e
2220 __MÉTODO__
2221 __FUNCTION__ retorna apenas o nome da função enquanto __METHOD__ retorna o nome da
classe junto com
2222 o nome da função:
2223 <?php
2224 truque de classe
2225 {
2226 função pública doit ()
2227 {
2228 eco __FUNCTION__;
2229 }
2230 função pública doitagain ()
2231 {
2232 echo __METHOD__;
2233 }
2234 }
2235 $obj = novo truque ();
2236 $obj> doit (); //Saídas: doit
2237 $obj> doitagain (); //Saídas: truque :: doitagain
2238 Seção 7.2: Diferença entre __CLASS__, get_class () e
2239 get_called_class ()
2240 __CLASS__ magic constant retorna o mesmo resultado que a função get_class () chamada
sem parâmetros e eles
2241 ambos retornam o nome da classe onde ela foi definida (ou seja, onde você escreveu o
nome da chamada /constante da função)
2242 Em contraste, as funções get_class ($this) e get_called_class (), retornarão o nome
da classe real
2243 que foi instanciado:
2244 <?php
2245 class Definition_Class {
2246 função pública say () {
2247 echo '__CLASS__ valor:' __CLASSE__ "\ n";
2248 echo 'get_called_class () valor:' get_called_class () "\ n";
2249 echo 'get_class ($this) valor:' get_class ($this) "\ n";
2250 echo 'get_class () valor:' get_class () "\ n";
2251 }
2252 }
2253 classe Actual_Class extends Definition_Class {}
2254 $c = new Actual_Class ();
2255 $c> say ();
2256 //Output:
2257 //__CLASS__ value: Definition_Class
2258 //get_called_class () value: Actual_Class
2259 //get_class ($this) value: Actual_Class
2260 FF
2261 Notas PHP para Profissionais 44
2262 //get_class () value: Definition_Class
2263 Seção 7.3: Constantes de arquivo e diretório
2264 Arquivo atual
2265 Você pode obter o nome do arquivo PHP atual (com o caminho absoluto) usando a
constante mágica __FILE__ Isto é
2266 mais frequentemente usado como uma técnica de registro /depuração
2267 echo "Estamos no arquivo:", __FILE__, "\ n";
2268 Diretório atual
2269 Para obter o caminho absoluto para o diretório onde o arquivo atual está localizado,
use a constante mágica __DIR__
2270 echo "Nosso script está localizado em:", __DIR__, "\ n";
2271 Para obter o caminho absoluto para o diretório em que o arquivo atual está
localizado, use o dirname (__FILE__)
2272 echo "Nosso script está localizado em:", dirname (__ FILE__), "\ n";
2273 Obtendo o diretório atual é freqüentemente usado por frameworks PHP para definir um
diretório base:
2274 //index.php do framework
2275 define (BASEDIR, __DIR__); //usando constante mágica para definir constante normal
2276 //somefile.php procura visualizações:
2277 $view = 'page';
2278 $viewFile = BASEDIR '/views /' $view;
2279 Separadores
2280 O sistema Windows entende perfeitamente os caminhos /in, portanto, o
DIRECTORY_SEPARATOR é usado principalmente quando
2281 caminhos de análise
2282 Além das constantes mágicas, o PHP também adiciona algumas constantes fixas para
trabalhar com caminhos:
2283 DIRECTORY_SEPARATOR constante para separar diretórios em um caminho Leva valor /on *
nix e \ no Windows.
2284 O exemplo com vistas pode ser reescrito com:
2285 $view = 'page';
2286 $viewFile = BASEDIR DIRECTORY_SEPARATOR .'views ' DIRECTORY_SEPARATOR $view;
2287 Raramente usada a constante PATH_SEPARATOR para separar caminhos na variável de
ambiente $PATH Isto é ; em
2288 Windows, caso contrário
2289 FF
2290 Notas PHP para Profissionais 45
2291 Capítulo 8: Comentários
2292 Seção 8.1: Comentários de linha única
2293 O comentário de linha única começa com "//" ou "#" Quando encontrado, todo o texto à
direita será ignorado pelo PHP
2294 intérprete
2295 //Este é um comentário
2296 # Este também é um comentário
2297 eco "Olá mundo!"; //Este também é um comentário, começando onde vemos "//"
2298 Seção 8.2: Comentários de múltiplas linhas
2299 O comentário de várias linhas pode ser usado para comentar grandes blocos de código
Começa com /* e termina com */.
2300 /* Este é um comentário de várias linhas
2301 Ele abrange várias linhas
2302 Isso ainda faz parte do comentário
2303 */
2304 FF
2305 Notas PHP para Profissionais 46
2306 Capítulo 9: Tipos
2307 Seção 9.1: Comparação de tipos
2308 Existem dois tipos de comparação: comparação frouxa com == e comparação estrita com
=== Comparação estrita
2309 garante que o tipo e o valor de ambos os lados do operador sejam os mesmos
2310 //Comparações frouxas
2311 var_dump (1 == 1); //verdade
2312 var_dump (1 == "1"); //verdade
2313 var_dump (1 == verdadeiro); //verdade
2314 var_dump (0 == false); //verdade
2315 //Comparações estritas
2316 var_dump (1 === 1); //verdade
2317 var_dump (1 === "1"); //false
2318 var_dump (1 === true); //false
2319 var_dump (0 == false); //false
2320 //Excepcional exceção: NAN nunca é igual a nada
2321 var_dump (NAN == NAN); //false
2322 var_dump (NAN === NAN); //false
2323 Você também pode usar uma comparação forte para verificar se o tipo e o valor não
correspondem usando! ==
2324 Um exemplo típico em que o operador == não é suficiente, são funções que podem
retornar tipos diferentes, como strpos,
2325 que retorna false se a palavra de pesquisa não for encontrada e a posição de
correspondência (int), caso contrário:
2326 if (strpos ('texto', 'palavra de pesquisa') == falso)
2327 //strpos retorna false, então == a comparação funciona como esperado aqui, MAS:
2328 if (strpos ('texto bla', 'texto') == falso)
2329 //strpos retorna 0 (correspondência encontrada na posição 0) e 0 == false é true
2330 //Isso provavelmente não é o que você espera!
2331 if (strpos ('texto', 'texto') === falso)
2332 //strpos retorna 0 e 0 === false é false, portanto, isso funciona como esperado
2333 Seção 9.2: Booleano
2334 Boolean é um tipo com dois valores, denotado como verdadeiro ou falso
2335 Este código define o valor de $foo como true e $bar como false:
2336 $foo = true;
2337 $bar = false;
2338 true e false não diferenciam maiúsculas de minúsculas, então TRUE e FALSE também
podem ser usados, até mesmo o FaLsE é possível Usando menor
2339 case é mais comum e recomendado na maioria dos guias de estilo de código, por
exemplo, PSR2
2340 Booleanos podem ser usados em declarações como esta:
2341 if ($foo) {//o mesmo que avaliar if ($foo == true)
2342 eco "verdadeiro";
2343 }
2344 Devido ao fato de que o PHP é fracamente tipado, se $foo acima é diferente de
verdadeiro ou falso, ele é automaticamente coagido para um
2345 valor booleano.
2346 FF
2347 Notas PHP para Profissionais 47
2348 Os seguintes valores resultam em falso:
2349 um valor zero: 0 (inteiro), 0.0 (float) ou '0' (string)
2350 uma string vazia '' ou array []
2351 null (o conteúdo de uma variável não definida ou atribuída a uma variável)
2352 Qualquer outro valor resulta em verdadeiro
2353 Para evitar essa comparação, você pode impor uma comparação forte usando ===, que
compara o valor e o tipo Vejo
2354 Digite Comparação para detalhes
2355 Para converter um tipo em booleano, você pode usar o (bool) ou (booleano) convertido
antes do tipo
2356 var_dump ((bool) "1"); //avalia como true
2357 ou ligue para a função boolval:
2358 var_dump (boolval ("1")); //avalia como true
2359 Conversão booleana em uma string (note que false produz uma string vazia):
2360 var_dump ((string) true); //string (1) "1"
2361 var_dump ((string) false); //string (0) ""
2362 Conversão booleana em um inteiro:
2363 var_dump ((int) true); //int (1)
2364 var_dump ((int) false); //int (0)
2365 Note que o oposto também é possível:
2366 var_dump ((bool) ""); //bool (false)
2367 var_dump ((bool) 1); //bool (true)
2368 Também tudo diferente de zero retornará verdadeiro:
2369 var_dump ((bool) 2); //bool (true)
2370 var_dump ((bool) "foo"); //bool (true)
2371 var_dump ((bool) 2.3e5); //bool (true)
2372 var_dump ((bool) array (12)); //bool (true)
2373 var_dump ((bool) array ()); //bool (false)
2374 var_dump ((bool) "false"); //bool (true)
2375 Seção 9.3: Flutuar
2376 $float = 0.123;
2377 Por razões históricas, "double" é retornado por gettype () no caso de um float, e
não simplesmente "float"
2378 Flutuadores são números de ponto flutuante, que permitem mais precisão de saída do
que inteiros simples
2379 Flutuadores e números inteiros podem ser usados juntos devido ao lançamento de tipos
de variáveis soltos no PHP:
2380 FF
2381 Notas PHP para Profissionais 48
2382 $sum = 3 + 0,14;
2383 echo $sum; //3,14
2384 php não mostra float como número float como outras linguagens, por exemplo:
2385 $var = 1;
2386 echo ((flutuação) $var); //retorna 1 não 1.0
2387 Aviso
2388 Precisão de ponto flutuante
2389 (Da página de manual do PHP)
2390 Números de ponto flutuante têm precisão limitada Embora dependa do sistema, o PHP
normalmente
2391 erro relativo máximo devido a arredondamentos na ordem de 1.11e16 Operações
aritméticas não elementares
2392 pode causar erros maiores, e a propagação de erros deve ser considerada quando
várias operações
2393 composto
2394 Além disso, números racionais que são exatamente representáveis como números de
ponto flutuante na base 10, como
2395 0,1 ou 0,7, não tem uma representação exata como números de ponto flutuante na base
2 (binário), que é usado
2396 internamente, não importa o tamanho da mantissa Portanto, eles não podem ser
convertidos em seu binário interno
2397 homólogos sem uma pequena perda de precisão Isso pode levar a resultados confusos:
por exemplo,
2398 floor ((0.1 + 0.7) * 10) normalmente retornará 7 ao invés do esperado 8, já que a
representação interna será
2399 algo como 7.9999999999999991118
2400 Portanto, nunca confie nos resultados do número flutuante ao último dígito e não
compare os números de ponto flutuante
2401 diretamente pela igualdade Se uma precisão maior for necessária, as funções
matemáticas de precisão arbitrária e gmp
2402 funções estão disponíveis
2403 Seção 9.4: Cordas
2404 Uma string no PHP é uma série de caracteres de byte único (ou seja, não há suporte
Unicode nativo) que pode ser especificado em
2405 quatro maneiras:
2406 Único citado
2407 Exibe as coisas quase completamente "como estão" Variáveis e a maioria das
seqüências de escape não serão interpretadas o
2408 exceção é que para exibir uma aspa simples literal, podese escapar com uma barra
invertida ', e para exibir uma barra invertida,
2409 podese escapar com outra barra invertida
2410 $my_string = 'Nada é analisado, exceto um apóstrofo de escape ou barra invertida
$foo \ n ';
2411 var_dump ($my_string);
2412 /*
2413 string (68) "Nada é analisado, exceto um apóstrofo ou barra invertida $foo \ n"
2414 */
2415 Duplo citado
2416 FF
2417 Notas PHP para Profissionais 49
2418 Ao contrário de uma string entre aspas simples, os nomes das variáveis simples e as
seqüências de escape nas strings serão avaliados Encaracolado
2419 chaves (como no último exemplo) podem ser usadas para isolar nomes de variáveis
complexas
2420 $variable1 = "Teste!";
2421 $variable2 = ["Testando?", ["Falha", "Sucesso"]];
2422 $my_string = "Variáveis e caracteres de escape são analisados: \ n \ n";
2423 $my_string = "$variável1 \ n \ n $variável2 [0] \ n \ n";
2424 $my_string = "Existem limites: $variable2 [1] [0]";
2425 $my_string = "Mas podemos contornálos envolvendo a variável inteira entre chaves:
2426 {$variável2 [1] [1]} ";
2427 var_dump ($my_string);
2428 /*
2429 string (98) "Variáveis e caracteres de escape são analisados:
2430 Testando!
2431 Testando?
2432 Existem limites: Array [0] "
2433 Mas podemos contornálos envolvendo a variável inteira entre chaves:
2434 */
2435 Heredoc
2436 Em uma seqüência heredoc, nomes de variáveis e seqüências de escape são analisados
de maneira semelhante às cadeias de caracteres com aspas duplas,
2437 embora chaves não estejam disponíveis para nomes de variáveis complexas O início da
string é delimitado por <<< identificador,
2438 e o fim por identificador, onde identificador é qualquer nome PHP válido O
identificador final deve aparecer em uma linha
2439 por si próprio Nenhum espaço em branco é permitido antes ou depois do identificador,
embora, como qualquer linha em PHP, ele também deva ser
2440 terminado por um ponto e vírgula
2441 $variable1 = "Incluir blocos de texto é mais fácil";
2442 $my_string = <<< EOF
2443 Tudo é analisado da mesma maneira que uma string com aspas duplas,
2444 mas há vantagens $variable1; consultas de banco de dados e saída HTML
2445 pode se beneficiar dessa formatação
2446 Quando atingimos uma linha que contém nada além do identificador, a string termina
2447 EOF;
2448 var_dump ($my_string);
2449 /*
2450 string (268) "Tudo é analisado da mesma maneira que uma string de aspas duplas,
2451 mas há vantagens Incluindo blocos de texto é mais fácil; consultas de banco de dados
e saída HTML
2452 pode se beneficiar dessa formatação
2453 Quando atingimos uma linha que contém nada além do identificador, a string termina "
2454 */
2455 Nowdoc
2456 Uma string nowdoc é como a versão com aspas simples de heredoc, embora nem mesmo as
seqüências de escape mais básicas
2457 são avaliados O identificador no início da string é encapsulado em aspas simples.
2458 Versão do PHP 5.x = 5.3
2459 $my_string = <<< 'EOF'
2460 Uma sintaxe semelhante a heredoc mas, semelhante a cadeias de caracteres simples
entre aspas,
2461 nada é analisado (nem mesmo apóstrofos escapados e barras invertidas \\.)
2462 FF
2463 Notas PHP para Profissionais 50
2464 EOF;
2465 var_dump ($my_string);
2466 /*
2467 string (116) "Uma sintaxe similar a heredoc mas similar a strings entre aspas
simples,
2468 nada é analisado (nem mesmo apóstrofos escapados e 'backslashes \\.) "
2469 */
2470 Seção 9.5: Callable
2471 Os callables são tudo o que pode ser chamado como retorno de chamada Coisas que
podem ser chamadas de "callback" são as seguintes:
2472 Funções anônimas
2473 Funções PHP padrão (nota: não construções de linguagem)
2474 Classes Estáticas
2475 Classes não estáticas (usando uma sintaxe alternativa)
2476 Métodos específicos de objeto /classe
2477 Objetos em si, desde que o objeto seja encontrado na chave 0 de um array
2478 Exemplo de referenciamento de um objeto como um elemento de matriz:
2479 $obj = new MyClass ();
2480 call_user_func ([$obj, 'myCallbackMethod']);
2481 Callbacks podem ser denotados por uma dica de tipo que pode ser chamada a partir do
PHP 5.4
2482 $callable = function () {
2483 valor de retorno';
2484 };
2485 função call_something (callable $fn) {
2486 call_user_func ($fn);
2487 }
2488 call_something ($chamavel);
2489 Seção 9.6: Recursos
2490 Um recurso é um tipo especial de variável que faz referência a um recurso externo,
como um arquivo, soquete, fluxo,
2491 documento ou conexão
2492 $file = fopen ('/etc /passwd', 'r');
2493 echo gettype ($arquivo);
2494 # Out: recurso
2495 echo $file;
2496 # Out: ID do recurso # 2
2497 Existem diferentes (sub) tipos de recursos Você pode verificar o tipo de recurso
usando get_resource_type ():
2498 $file = fopen ('/etc /passwd', 'r');
2499 FF
2500 Notas PHP para Profissionais 51
2501 echo get_resource_type ($file);
2502 #Out: stream
2503 $sock = fsockopen ('www.google.com', 80);
2504 echo get_resource_type ($sock);
2505 #Out: stream
2506 Você pode encontrar uma lista completa de tipos de recursos internos aqui
2507 Seção 9.7: Fundição de Tipo
2508 O PHP geralmente irá adivinhar corretamente o tipo de dados que você pretende usar a
partir do contexto em que é usado, no entanto, às vezes
2509 é útil forçar manualmente um tipo Isso pode ser feito prefixando a declaração com o
nome da
2510 tipo exigido entre parênteses:
2511 $bool = true;
2512 var_dump ($bool); //bool (true)
2513 $int = (int) true;
2514 var_dump ($int); //int (1)
2515 $string = (string) verdadeiro;
2516 var_dump ($string); //string (1) "1"
2517 $string = (string) falsa;
2518 var_dump ($string); //string (0) ""
2519 $float = (float) true;
2520 var_dump ($float); //float (1)
2521 $array = ['x' => 'y'];
2522 var_dump ((objeto) $array); //objeto (stdClass) # 1 (1) {["x"] => string (1) "y"}
2523 $object = new stdClass ();
2524 $object> x = 'y';
2525 var_dump ((array) $objeto); //array (1) {["x"] => string (1) "y"}
2526 $string = "asdf";
2527 var_dump ((não configurado) $string); //NULO
2528 Mas tenha cuidado: nem todos os tipos de conversão funcionam como se poderia esperar:
2529 //abaixo de 3 declarações para sistemas de 32 bits (PHP_INT_MAX = 2147483647)
2530 //um valor inteiro maior que PHP_INT_MAX é automaticamente convertido para float:
2531 var_dump (999888777666); //float (999888777666)
2532 //forçando para (int) dá estouro:
2533 var_dump ((int) 999888777666); //int (838602302)
2534 //mas em uma string apenas retorna PHP_INT_MAX
2535 var_dump ((int) "999888777666"); //int (2147483647)
2536 var_dump ((bool) []); //bool (false) (array vazio)
2537 var_dump ((bool) [false]); //bool (true) (array não vazio)
2538 Seção 9.8: Juggling Type
2539 PHP é uma linguagem de tipagem fraca Não requer declaração explícita de tipos de
dados O contexto em que o
2540 variável é usada determina seu tipo de dados; a conversão é feita automaticamente:
2541 $a = "2"; //corda
2542 FF
2543 Notas PHP para Profissionais 52
2544 $a = $a + 2; //integer (4)
2545 $a = $a + 0,5; //float (4.5)
2546 $a = 1 + "2 laranjas"; //integer (3)
2547 Seção 9.9: Nulo
2548 PHP representa "sem valor" com a palavrachave nula É um pouco semelhante ao ponteiro
nulo na linguagem C e ao
2549 Valor NULL no SQL
2550 Definindo a variável como null:
2551 $nullvar = null; //diretamente
2552 função doSomething () {} //esta função não retorna nada
2553 $nullvar = doSomething (); //então o nulo é atribuído a $nullvar
2554 Verificando se a variável foi definida como nula:
2555 if (is_null ($nullvar)) {/* a variável é nula */}
2556 if ($nullvar === null) {/* variável é nulo */}
2557 Variável nula vs indefinida
2558 Se a variável não foi definida ou não foi definida, então quaisquer testes contra o
nulo serão bemsucedidos, mas eles também serão
2559 gerar um aviso: variável indefinida: nullvar:
2560 $nullvar = null;
2561 unset ($nullvar);
2562 if ($nullvar === null) {/* true mas também um aviso é impresso */}
2563 if (is_null ($nullvar)) {/* true mas também um aviso é impresso */}
2564 Portanto, os valores indefinidos devem ser verificados com isset:
2565 if (! isset ($nullvar)) {/* a variável é nula ou não está definida */}
2566 Seção 9.10: Inteiros
2567 Inteiros em PHP podem ser especificados nativamente na base 2 (binária), na base 8
(octal), na base 10 (decimal) ou na base 16
2568 (hexadecimal)
2569 $my_decimal = 42;
2570 $my_binary = 0b101010;
2571 $my_octal = 052;
2572 $my_hexadecimal = 0x2a;
2573 echo ($my_binary + $my_octal) /2;
2574 //A saída está sempre em decimal: 42
2575 Os inteiros têm 32 ou 64 bits, dependendo da plataforma A constante PHP_INT_SIZE
retém o tamanho inteiro em bytes.
2576 PHP_INT_MAX e (desde PHP 7.0) PHP_INT_MIN também estão disponíveis
2577 printf ("Integers are% d bits long" PHP_EOL, PHP_INT_SIZE * 8);
2578 printf ("Eles vão até% d" PHP_EOL, PHP_INT_MAX);
2579 Valores inteiros são criados automaticamente conforme a necessidade de floats,
booleans e strings Se um typecast explícito é
2580 FF
2581 Notas PHP para Profissionais 53
2582 necessário, isso pode ser feito com o elenco (int) ou (inteiro):
2583 $my_numeric_string = "123";
2584 var_dump ($my_numeric_string);
2585 //Output: string (3) "123"
2586 $my_integer = (int) $my_numeric_string;
2587 var_dump ($my_integer);
2588 //Output: int (123)
2589 O estouro de inteiro será manipulado pela conversão para um float:
2590 $too_big_integer = PHP_INT_MAX + 7;
2591 var_dump ($too_big_integer);
2592 //Output: float (9.2233720368548E + 18)
2593 Não existe um operador de divisão inteira no PHP, mas ele pode ser simulado usando
uma conversão implícita, que sempre 'arredonda' por
2594 apenas descartando a parte flutuante A partir do PHP versão 7, uma função de divisão
de inteiros foi adicionada.
2595 $not_an_integer = 25/4;
2596 var_dump ($not_an_integer);
2597 //Output: float (6.25)
2598 var_dump ((int) (25/4)); //(ver nota abaixo)
2599 //Output: int (6)
2600 var_dump (intdiv (25/4)); //a partir do PHP7
2601 //Output: int (6)
2602 (Note que os parênteses extras ao redor (25/4) são necessários porque o (int) elenco
tem precedência mais alta do que
2603 a divisão)
2604 FF
2605 Notas PHP para Profissionais 54
2606 Capítulo 10: Operadores
2607 Um operador é algo que recebe um ou mais valores (ou expressões, no jargão de
programação) e gera
2608 outro valor (para que a construção se torne uma expressão)
2609 Os operadores podem ser agrupados de acordo com o número de valores que eles recebem
2610 Seção 10.1: Operador Coalescente Nulo (???)
2611 A coalescência nula é um novo operador introduzido no PHP 7 Esse operador retorna
seu primeiro operando se estiver definido e não
2612 NULO Caso contrário, retornará seu segundo operando.
2613 O exemplo a seguir:
2614 $name = $_POST ['nome'] ?? 'ninguém';
2615 é equivalente a ambos:
2616 if (isset ($_ POST ['nome'])) {
2617 $name = $_POST ['nome'];
2618 } outro {
2619 $name = 'nobody';
2620 }
2621 e:
2622 $name = isset ($_ POST ['nome'])? $_POST ['name']: 'nobody';
2623 Este operador também pode ser encadeado (com semântica associativa à direita):
2624 $name = $_GET ['nome'] ?? $_POST ['nome'] ?? 'ninguém';
2625 que é equivalente a:
2626 if (isset ($_ GET ['nome'])) {
2627 $name = $_GET ['nome'];
2628 } elseif (isset ($_ POST ['nome']))) {
2629 $name = $_POST ['nome'];
2630 } outro {
2631 $name = 'nobody';
2632 }
2633 Nota:
2634 Ao usar o operador de coalescência na concatenação de strings, não esqueça de usar
parênteses ()
2635 $firstName = "John";
2636 $lastName = "Doe";
2637 echo $firstName ?? "Desconhecido" "" $lastName ?? "";
2638 Isso produzirá somente João, e se seu $firstName for null e $lastName for Doe, ele
gerará uma Unknown Doe A fim de
2639 saída John Doe, devemos usar parênteses como este
2640 $firstName = "John";
2641 $lastName = "Doe";
2642 FF
2643 Notas PHP para Profissionais 55
2644 echo ($firstName ?? "Desconhecido") "" ($lastName ?? "");
2645 Isso produzirá John Doe em vez de John apenas
2646 Seção 10.2: Operador de Nave Espacial (<=>)
2647 O PHP 7 introduz um novo tipo de operador, que pode ser usado para comparar
expressões Este operador retornará 1, 0
2648 ou 1 se a primeira expressão for menor que, igual a ou maior que a segunda expressão
2649 //inteiros
2650 imprimir (1 <=> 1); //0
2651 imprimir (1 <=> 2); //1
2652 imprimir (2 <=> 1); //1
2653 //Floats
2654 impressão (1.5 <=> 1.5); //0
2655 impressão (1.5 <=> 2.5); //1
2656 impressão (2.5 <=> 1.5); //1
2657 //Cordas
2658 print ("a" <=> "a"); //0
2659 print ("a" <=> "b"); //1
2660 print ("b" <=> "a"); //1
2661 Objetos não são comparáveis e, portanto, isso resultará em um comportamento
indefinido
2662 Este operador é particularmente útil ao escrever uma função de comparação definida
pelo usuário usando usort, uasort ou
2663 uksort Dada uma matriz de objetos a serem classificados por sua propriedade de peso,
por exemplo, uma função anônima pode
2664 use <=> para retornar o valor esperado pelas funções de classificação
2665 usort ($list, function ($a, $b) {return $a> peso <=> $b> peso;});
2666 No PHP 5, isso exigiria uma expressão mais elaborada
2667 usort ($list, function ($a, $b) {
2668 devolver $a> peso <$b> peso? 1: ($a> peso == $b> peso? 0: 1);
2669 });
2670 Seção 10.3: Operador de Execução (``)
2671 O operador de execução do PHP consiste em backticks (``) e é usado para executar
comandos do shell A saída do
2672 O comando será retornado e pode, portanto, ser armazenado em uma variável
2673 //Listar arquivos
2674 $output = `ls`;
2675 echo "<pre> $output </pre>";
2676 Observe que o operador de execução e o shell_exec () fornecerão o mesmo resultado
2677 Seção 10.4: Operadores de Incremento (++) e Decrementação
2678 ()
2679 Variáveis podem ser incrementadas ou decrementadas por 1 com ++ ou , respectivamente
Eles podem preceder ou ter sucesso
2680 variáveis e ligeiramente variam semanticamente, como mostrado abaixo.
2681 FF
2682 Notas PHP para Profissionais 56
2683 $i = 1;
2684 echo $i; //Imprime 1
2685 //O operador de préincremento incrementa $i em um e retorna $i
2686 echo ++ $i; //Imprime 2
2687 //O operador prédecremento decrementa $i em um e retorna $i
2688 echo $i; //Imprime 1
2689 //O operador pósincremento retorna $i e, em seguida, incrementa $i em um
2690 echo $i ++; //Imprime 1 (mas o valor de $i agora é 2)
2691 //Operador pósdecremento retorna $i e decrementa $i em um
2692 echo $i; //Imprime 2 (mas o valor de $i é agora 1)
2693 Mais informações sobre como incrementar e decrementar operadores podem ser
encontradas na documentação oficial
2694 Seção 10.5: Operador Ternário (? :)
2695 O operador ternário pode ser considerado como uma instrução inline if Consiste em
três partes O operador e dois
2696 resultados A sintaxe é a seguinte:
2697 $value = <operator> <valor verdadeiro>: <valor falso>
2698 Se o operador for avaliado como verdadeiro, o valor no primeiro bloco será retornado
(<valor verdadeiro>), senão o valor no
2699 o segundo bloco será retornado (<valor falso>) Como estamos definindo $value para o
resultado do nosso operador ternário,
2700 armazenará o valor retornado
2701 Exemplo:
2702 $action = empty ($_ POST ['ação'])? 'default': $_POST ['ação'];
2703 $action conteria a string 'default' se vazio ($_ POST ['action']) é avaliado como
true Caso contrário, seria
2704 contém o valor de $_POST ['action']
2705 A expressão (expr1)? (expr2): (expr3) avalia para expr2 se expr1valor para true e
expr3 se expr1
2706 avalia para falso
2707 É possível deixar de fora a parte central do operador ternário Expressão expr1?:
Expr3 retorna expr1 se expr1
2708 avalia como TRUE e expr3 caso contrário ?: é freqüentemente chamado de operador de
Elvis.
2709 Isso se comporta como o operador Coalescente Nulo, exceto que ?? requer que o
operando da esquerda seja exatamente nulo enquanto
2710 ?: tenta resolver o operando da esquerda para um valor booleano e verificar se ele é
falso para booleano
2711 Exemplo:
2712 function setWidth (int $width = 0) {
2713 $_SESSION ["width"] = $width?: GetDefaultWidth ();
2714 }
2715 Neste exemplo, setWidth aceita um parâmetro de largura ou o padrão 0 para alterar o
valor da sessão de largura Se $largura é 0
2716 (se $width não for fornecido), que será resolvido como boolean false, o valor de
getDefaultWidth () será usado no lugar o
2717 A função getDefaultWidth () não será chamada se $width não for resolvido como
booleano false
2718 Consulte Tipos para obter mais informações sobre conversão de variáveis em booleanas.
2719 FF
2720 Notas PHP para Profissionais 57
2721 Seção 10.6: Operadores lógicos (&& /AND e || /OR)
2722 No PHP, existem duas versões dos operadores lógicos AND e OR
2723 Operador Verdadeiro se
2724 $a e $b Ambos $a e $b são verdadeiros
2725 $a && $b Tanto $a quanto $b são verdadeiros
2726 $a ou $b Ou $a ou $b é verdadeiro
2727 $a || $b Ou $a ou $b é verdadeiro
2728 Note que o && e || Operadores têm maior precedência que e /ou Veja a tabela abaixo:
2729 Resultado da Avaliação de $e Avaliado como
2730 $e = false || true True $e = (false || true)
2731 $e = false ou true False ($e = false) ou true
2732 Por isso, é mais seguro usar o && and || em vez de e e ou.
2733 Seção 10.7: Operadores de String ( E =)
2734 Existem apenas dois operadores de string:
2735 Concatenação de duas cordas (ponto):
2736 $a = "a";
2737 $b = "b";
2738 $c = $a $b; //$c => "ab"
2739 Concatenating assignment (dot =):
2740 $a = "a";
2741 $a = "b"; //$a => "ab"
2742 Seção 10.8: Operadores de objetos e classes
2743 Os membros de objetos ou classes podem ser acessados usando o operador de objeto (>)
e o operador de classe (: :)
2744 class MyClass {
2745 public $a = 1;
2746 public static $b = 2;
2747 const C = 3;
2748 função pública d () {return 4; }
2749 função estática pública e () {return 5; }
2750 }
2751 $object = new MyClass ();
2752 var_dump ($object> a); //int (1)
2753 var_dump ($object :: $b); //int (2)
2754 var_dump ($object :: C); //int (3)
2755 var_dump (MyClass :: $b); //int (2)
2756 var_dump (MyClass :: C); //int (3)
2757 var_dump ($object> d ()); //int (4)
2758 var_dump ($object :: d ()); //int (4)
2759 var_dump (MyClass :: e ()); //int (5)
2760 $classname = "MyClass";
2761 FF
2762 Notas PHP para Profissionais 58
2763 var_dump ($classname :: e ()); //também funciona! int (5)
2764 Note que depois do operador object, o $não deve ser escrito ($object> a em vez de
$object > $a) Para a turma
2765 operador, este não é o caso e o $é necessário Para uma constante definida na classe,
o $nunca é usado.
2766 Observe também que var_dump (MyClass :: d ()); só é permitido se a função d () não
referenciar o objeto:
2767 class MyClass {
2768 private $a = 1;
2769 função pública d () {
2770 retornar $this> a;
2771 }
2772 }
2773 $object = new MyClass ();
2774 var_dump (MyClass :: d ()); //Erro!
2775 Isso causa um erro fatal do PHP: Erro não detectado: usando $this quando não está no
contexto do objeto
2776 Esses operadores deixaram a associatividade, que pode ser usada para 'encadeamento':
2777 class MyClass {
2778 private $a = 1;
2779 public function add (int $a) {
2780 $this> a + = $a;
2781 retorne $this;
2782 }
2783 função pública get () {
2784 retornar $this> a;
2785 }
2786 }
2787 $object = new MyClass ();
2788 var_dump ($object> add (4) > get ()); //int (5)
2789 Esses operadores têm a maior precedência (eles nem sequer são mencionados no
manual), ainda mais alto que o clone
2790 Portanto:
2791 class MyClass {
2792 private $a = 0;
2793 public function add (int $a) {
2794 $this> a + = $a;
2795 retorne $this;
2796 }
2797 função pública get () {
2798 retornar $this> a;
2799 }
2800 }
2801 $o1 = new MyClass ();
2802 $o2 = clone $o1> adicionar (2);
2803 var_dump ($o1> get ()); //int (2)
2804 var_dump ($o2> get ()); //int (2)
2805 O valor de $o1 é adicionado antes de o objeto ser clonado!
2806 Note que usar parênteses para influenciar a precedência não funcionou na versão 5 e
mais antiga do PHP (ele faz no PHP 7):
2807 FF
2808 Notas PHP para Profissionais 59
2809 //usando a classe MyClass do código anterior
2810 $o1 = new MyClass ();
2811 $o2 = (clone $o1) > add (2); //Erro no PHP 5 e antes, tudo bem no PHP 7
2812 var_dump ($o1> get ()); //int (0) no PHP 7
2813 var_dump ($o2> get ()); //int (2) no PHP 7
2814 Seção 10.9: Atribuição combinada (+ = etc)
2815 Os operadores de atribuição combinados são um atalho para uma operação em alguma
variável e subseqüentemente atribuindo
2816 esse novo valor para essa variável
2817 Aritmética:
2818 $a = 1; //tarefa básica
2819 $a + = 2; //leia como '$a = $a + 2'; $a agora é (1 + 2) => 3
2820 $a = 1; //$a now é (3 1) => 2
2821 $a * = 2; //$a now é (2 * 2) => 4
2822 $a /= 2; //$a agora é (16/2) => 8
2823 $a% = 5; //$a now é (8% 5) => 3 (módulo ou resto)
2824 //array +
2825 $arrOne = array (1);
2826 $arrTwo = array (2);
2827 $arrOne + = $arrTwo;
2828 Processando várias matrizes juntas
2829 $a ** = 2; //$a now é (4 ** 2) => 16 (4 elevado à potência de 2)
2830 Concatenação combinada e atribuição de uma string:
2831 $a = "a";
2832 $a = "b"; //$a => "ab"
2833 Operadores binários combinados de atribuição bit a bit:
2834 $a = 0b00101010; //$a agora é 42
2835 $a & = 0b00001111; //$a agora é (00101010 e 00001111) => 00001010 (bit a bit e)
2836 $a | = 0b00100010; //$a now é (00001010 | 00100010) => 00101010 (bit a bit ou)
2837 $a ^ = 0b10000010; //$a agora é (00101010 ^ 10000010) => 10101000 (bit a bit xor)
2838 $a >> = 3; //$a now é (10101000 >> 3) => 00010101 (deslocar para a direita por 3)
2839 $a << = 1; //$a agora é (00010101 << 1) => 00101010 (shift left por 1)
2840 Seção 10.10: Alterando a precedência do operador (com
2841 parênteses)
2842 A ordem em que os operadores são avaliados é determinada pela precedência do
operador (ver também as Observações)
2843 seção)
2844 Em
2845 $a = 2 * 3 + 4;
2846 $a recebe um valor de 10 porque 2 * 3 é avaliado primeiro (a multiplicação tem uma
precedência maior que a adição)
2847 um subresultado de 6 + 4, que é igual a 10.
2848 FF
2849 Notas PHP para Profissionais 60
2850 A precedência pode ser alterada usando parênteses: em
2851 $a = 2 * (3 + 4);
2852 $a recebe um valor de 14 porque (3 + 4) é avaliado primeiro
2853 Seção 10.11: Atribuição Básica (=)
2854 $a = "alguma string";
2855 resulta em $a tendo o valor alguma string
2856 O resultado de uma expressão de atribuição é o valor que está sendo atribuído Note
que um único sinal de igual = NÃO é para
2857 comparação!
2858 $a = 3;
2859 $b = ($a = 5);
2860 faz o seguinte:
2861 1 A linha 1 atribui 3 a $a
2862 2 A linha 2 atribui 5 a $a Essa expressão também gera valor 5.
2863 3 A linha 2 atribui o resultado da expressão entre parênteses (5) a $b
2864 Assim: tanto $a quanto $b agora possuem valor 5
2865 Seção 10.12: Associação
2866 Associação à esquerda
2867 Se a precedência de dois operadores for igual, a associatividade determina o
agrupamento (ver também as Observações)
2868 seção):
2869 $a = 5 * 3% 2; //$a agora é (5 * 3)% 2 => (15% 2) => 1
2870 * e% têm igual precedência e associatividade à esquerda Porque a multiplicação
ocorre primeiro (esquerda), é agrupada.
2871 $a = 5% 3 * 2; //$a agora é (5% 3) * 2 => (2 * 2) => 4
2872 Agora, o operador de módulo ocorre primeiro (à esquerda) e é assim agrupado
2873 Associação certa
2874 $a = 1;
2875 $b = 1;
2876 $a = $b + = 1;
2877 Tanto $a quanto $b agora têm valor 2 porque $b + = 1 é agrupado e então o resultado
($b é 2) é atribuído a $a
2878 Seção 10.13: Operadores de comparação
2879 Igualdade
2880 Para o teste básico de igualdade, o operador igual == é usado Para verificações mais
abrangentes, use o operador idêntico
2881 ===
2882 FF
2883 Notas PHP para Profissionais 61
2884 O operador idêntico funciona da mesma forma que o operador de igualdade, exigindo
que seus operandos tenham o mesmo valor, mas também
2885 exige que eles tenham o mesmo tipo de dados
2886 Por exemplo, o exemplo abaixo mostrará 'aeb são iguais', mas não 'aeb são idênticos'
2887 $a = 4;
2888 $b = '4';
2889 if ($a == $b) {
2890 eco 'aeb são iguais'; //isso será impresso
2891 }
2892 if ($a === $b) {
2893 echo 'aeb são idênticos'; //isso não será impresso
2894 }
2895 Ao usar o operador equal, as cadeias numéricas são convertidas em números inteiros
2896 Comparação de objetos
2897 === compara dois objetos verificando se eles são exatamente a mesma instância Isso
significa que o novo stdClass () ===
2898 new stdClass () resolve para falso, mesmo que eles sejam criados da mesma maneira (e
tenham exatamente os mesmos valores)
2899 == compara dois objetos verificando recursivamente se eles são iguais (deep equals)
Isso significa que, por $a == $b, se $a e
2900 $b são:
2901 1 da mesma classe
2902 2 ter as mesmas propriedades definidas, incluindo propriedades dinâmicas
2903 3 para cada propriedade $conjunto de propriedades, $a> propriedade == $b>
propriedade é verdadeira (portanto, recursivamente verificada)
2904 Outros operadores comumente usados
2905 Eles incluem:
2906 1 Maior que (>)
2907 2 Menor que (<)
2908 3 Maior que ou igual a (> =)
2909 4 Menor ou igual a (<=)
2910 5 Não é igual a (! =)
2911 6 Não Igual Igual a (! ==)
2912 1 Maior que: $a> $b, retorna verdadeiro se o valor de $a for maior que $b, caso
contrário, retorna falso
2913 Exemplo:
2914 var_dump (5> 2); //imprime bool (true)
2915 var_dump (2> 7); //imprime bool (false)
2916 2 Menor que: $a <$b, retorna verdadeiro se o valor de $a for menor que $b, caso
contrário, retorna falso
2917 Exemplo:
2918 var_dump (5 <2); //imprime bool (false)
2919 var_dump (1 <10); //imprime bool (true)
2920 3 Maior que ou igual a: $a> = $b, retorna verdadeiro se o valor de $a for maior que
$b ou igual a $b,
2921 caso contrário, retorna falso
2922 Exemplo:
2923 FF
2924 Notas PHP para Profissionais 62
2925 var_dump (2> = 2); //imprime bool (true)
2926 var_dump (6> = 1); //imprime bool (true)
2927 var_dump (1> = 7); //imprime bool (false)
2928 4 Menor que ou igual a: $a <= $b, retorna verdadeiro se o valor de $a for menor que
de $b ou igual a $b,
2929 caso contrário, retorna falso
2930 Exemplo:
2931 var_dump (5 <= 5); //imprime bool (true)
2932 var_dump (5 <= 8); //imprime bool (true)
2933 var_dump (9 <= 1); //imprime bool (false)
2934 5/6 Não igual /idêntico para: Para refazer o exemplo anterior sobre igualdade, o
exemplo abaixo exibirá 'aeb são
2935 não idêntico ', mas não' aeb não são iguais '
2936 $a = 4;
2937 $b = '4';
2938 if ($a! = $b) {
2939 eco 'aeb não são iguais'; //isso não será impresso
2940 }
2941 if ($a! == $b) {
2942 os ecos 'a e b não são idênticos'; //isso será impresso
2943 }
2944 Seção 10.14: Operadores Bitabit
2945 Prefixo operadores bit a bit
2946 Operadores bitwise são como operadores lógicos, mas executados por bit, em vez de
por valor booleano
2947 //bitwise NOT ~: define todos os bits não definidos e anula todos os bits definidos
2948 printf ("% '06b", ~ 0b110110); //001001
2949 Operadores de bitmaskbitmask
2950 Bitwise AND &: um bit é definido apenas se for definido em ambos os operandos
2951 printf ("% '06b", 0b110101 & 0b011001); //010001
2952 Bitwise OR |: um bit é definido se for definido em um ou ambos os operandos
2953 printf ("% '06b", 0b110101 | 0b011001); //111101
2954 Bitwise XOR ^: um bit é definido se for definido em um operando e não for definido
em outro operando, ou seja, somente se esse bit estiver em diferente
2955 estado nos dois operandos
2956 printf ("% '06b", 0b110101 ^ 0b011001); //101100
2957 Exemplos de uso de máscaras de bits
2958 Esses operadores podem ser usados para manipular máscaras de bits Por exemplo:
2959 file_put_contents ("file.log", LOCK_EX | FILE_APPEND);
2960 Aqui, o | operador é usado para combinar os dois bitmasks Embora + tenha o mesmo
efeito, | enfatiza que você
2961 FF
2962 Notas PHP para Profissionais 63
2963 estão combinando bitmasks, não adicionando dois inteiros escalares normais
2964 class Foo {
2965 const OPTION_A = 1;
2966 const OPTION_B = 2;
2967 const OPTION_C = 4;
2968 const OPTION_A = 8;
2969 private $options = self :: OPTION_A | self :: OPTION_C;
2970 função pública toggleOption (int $option) {
2971 $this> options ^ = $option;
2972 }
2973 função pública enable (int $option) {
2974 $this> options | = $option; //ativar $option independentemente do seu estado original
2975 }
2976 função pública disable (int $option) {
2977 $this> options & = ~ $option; //desativa $option independentemente do seu estado
original,
2978 //sem afetar outros bits
2979 }
2980 /** retorna se pelo menos uma das opções está ativada */
2981 função pública isOneEnabled (int $options): bool {
2982 retorne $this> options & $option! == 0;
2983 //Use! == em vez de>, porque
2984 //se $options é sobre um bit alto, podemos estar lidando com um inteiro negativo
2985 }
2986 /** retorna se todas as opções estão ativadas */
2987 função pública areAllEnabled (int $options): bool {
2988 return ($this> options & $options) === $opções;
2989 //observe os parênteses; cuidado com a precedência do operador
2990 }
2991 }
2992 Este exemplo (assumindo $opção sempre contém apenas um bit) usa:
2993 o operador ^ para alternar convenientemente as máscaras de bits
2994 o | operador para definir um pouco negligenciando seu estado original ou outros bits
2995 o operador ~ para converter um inteiro com apenas um bit definido em um inteiro com
apenas um bit não definido
2996 o operador & para desfazer um pouco, usando estas propriedades de &:
2997 Já que & = com um bit definido não fará nada ((1 & 1) === 1, (0 & 1) === 0), fazendo
& = com um inteiro
2998 com apenas um bit não definido, somente o bit não será afetado, não afetando outros
bits
2999 & = com um bit não definido irá desarmar esse bit ((1 & 0) === 0, (0 & 0) === 0)
3000 Usar o operador & com outra máscara de bits irá filtrar todos os outros bits não
definidos nessa máscara de bits
3001 Se a saída tiver algum bit definido, isso significa que qualquer uma das opções está
ativada
3002 Se a saída tiver todos os bits do conjunto de bitmask, isso significa que todas as
opções na máscara de bits estão ativadas
3003 Tenha em mente que estes operadores de comparação: (<> <=> = == ===! =! == <> <=>)
têm precedência mais alta que estes
3004 operadores do bitmaskbitmask: (| ^ &) Como os resultados bit a bit são
frequentemente comparados usando esses operadores de comparação,
3005 uma armadilha comum para estar ciente
3006 Operadores de deslocamento de bit
3007 Shift à esquerda bit a bit <<: desloca todos os bits para a esquerda (mais
significativos) pelo número de passos dado e descarta os bits
3008 excedendo o tamanho int
3009 FF
3010 Notas PHP para Profissionais 64
3011 << $x equivale a desabilitar os mais altos bits de x e multiplicar pela potência de
x de 2
3012 printf ("% '08b", 0b00001011 << 2); //00101100
3013 assert (PHP_INT_SIZE === 4); //um sistema de 32 bits
3014 printf ("% x,% x", 0x5FFFFFFF << 2, 0x1FFFFFFF << 4); //7FFFFFFC, FFFFFFFF
3015 Bitwise right shift >>: descarta o deslocamento mais baixo e desloca os bits
restantes para a direita (menos significativo)
3016 >> $x é equivalente a dividir pela potência $x de 2 e descartar a parte não inteira
3017 printf ("% x", 0xFFFFFFFF >> 3); //1FFFFFFF
3018 Exemplo de uso de mudança de bit:
3019 Divisão rápida por 16 (melhor desempenho que /= 16)
3020 $x >> = 4;
3021 Em sistemas de 32 bits, isso descarta todos os bits no inteiro, definindo o valor
como 0 Em sistemas de 64 bits, isso não
3022 32 bits significativos e manter o mínimo
3023 $x = $x << 32 >> 32;
3024 32 bits significativos, equivalentes a $x & 0xFFFFFFFF
3025 Nota: Neste exemplo, printf ("% '06b") é usado Emite o valor em 6 dígitos binários.
3026 Seção 10.15: instanceof (operador de tipo)
3027 Para verificar se algum objeto é de uma determinada classe, o operador instance
(binário) do operador pode ser usado desde o PHP
3028 versão 5
3029 O primeiro parâmetro (esquerdo) é o objeto a ser testado Se essa variável não for um
objeto, instanceof sempre retornará false Se um
3030 expressão constante é usada, um erro é lançado
3031 O segundo parâmetro (à direita) é a classe para comparação A classe pode ser
fornecida como o próprio nome da classe,
3032 variável de string contendo o nome da classe (não uma constante de string!) ou um
objeto dessa classe
3033 class MyClass {
3034 }
3035 $o1 = new MyClass ();
3036 $o2 = novo MyClass ();
3037 $name = 'MyClass';
3038 //nos casos abaixo, $a obtém o valor booleano true
3039 $a = $o1 instanceof MyClass;
3040 $a = $o1 instanceof $name;
3041 $a = $o1 instância de $o2;
3042 //counter examples:
3043 $b = 'b';
3044 $a = $o1 instanceof 'MyClass'; //erro de análise: constante não permitida
3045 $a = false instanceof MyClass; //erro fatal: constante não permitida
3046 $a = $b instanceof MyClass; //false ($b não é um objeto)
3047 FF
3048 Notas PHP para Profissionais 65
3049 instanceof também pode ser usado para verificar se um objeto é de alguma classe que
estende outra classe ou
3050 implementa alguma interface:
3051 interface MyInterface {
3052 }
3053 classe MySuperClass implementa MyInterface {
3054 }
3055 classe MySubClass estende MySuperClass {
3056 }
3057 $o = novo MySubClass ();
3058 //nos casos abaixo, $a obtém o valor booleano true
3059 $a = $o instanceof do MySubClass;
3060 $a = $o instanceof MySuperClass;
3061 $a = $o instanceof MyInterface;
3062 Para verificar se um objeto não é de alguma classe, o operador não (!) Pode ser
usado:
3063 class MyClass {
3064 }
3065 classe OtherClass {
3066 }
3067 $o = new MyClass ();
3068 $a =! $o instanceof OtherClass; //verdade
3069 Observe que os parênteses em torno de $o instanceof MyClass não são necessários
porque o instanceof tem maior precedência
3070 do que !, embora possa tornar o código mais legível com parênteses
3071 Ressalvas
3072 Se uma classe não existir, as funções de carregamento automático registradas serão
chamadas para tentar definir a classe (este é um tópico fora
3073 o escopo desta parte da Documentação!) Nas versões do PHP anteriores a 5.1.0, o
operador instanceof também
3074 disparar essas chamadas, definindo a classe (e se a classe não puder ser definida,
um erro fatal ocorreria)
3075 Para evitar isso, use uma string:
3076 //somente versões do PHP antes de 5.1.0!
3077 class MyClass {
3078 }
3079 $o = new MyClass ();
3080 $a = $o instanceof OtherClass; //OtherClass não está definido!
3081 //se o OtherClass puder ser definido em um autoloader registrado, ele será
3082 //loaded e $a obtém o valor booleano false ($o não é um OtherClass)
3083 //se a OtherClass não puder ser definida em um autoloader registrado, um
3084 //ocorreu um erro
3085 $name = 'YetAnotherClass';
3086 $a = $o instanceof $name; //YetAnotherClass não está definido!
3087 //$a simplesmente obtém valor booleano false, YetAnotherClass permanece indefinido
3088 A partir do PHP versão 5.1.0, os autocarregadores registrados não são mais chamados
nessas situações
3089 Versões mais antigas do PHP (antes de 5.0)
3090 FF
3091 Notas PHP para Profissionais 66
3092 Em versões mais antigas do PHP (antes de 5.0), a função is_a pode ser usada para
determinar se um objeto é de alguma classe
3093 Esta função foi preterida na versão 5 do PHP e não foi substituída na versão 5.3.0
do PHP.
3094 FF
3095 Notas PHP para Profissionais 67
3096 Capítulo 11: Referências
3097 Seção 11.1: Atribuir por referência
3098 Esta é a primeira fase de referência Essencialmente, quando você atribui por
referência, você está permitindo que duas variáveis
3099 compartilhe o mesmo valor como tal
3100 $foo = & $bar;
3101 $foo e $bar são iguais aqui Eles não apontam um para o outro Eles apontam para o
mesmo lugar (o "valor").
3102 Você também pode atribuir por referência dentro da construção da linguagem array ()
Embora não seja estritamente uma atribuição por
3103 referência
3104 $foo = 'oi';
3105 $bar = array (1, 2);
3106 $array = array (& $foo, & $bar [0]);
3107 Observe, no entanto, que as referências dentro de matrizes são potencialmente
perigosas Fazendo um normal (não por
3108 referência) atribuição com uma referência no lado direito não transforma o lado
esquerdo em uma referência, mas
3109 referências dentro de matrizes são preservadas nessas atribuições normais Isso
também se aplica a chamadas de função
3110 onde a matriz é passada por valor
3111 Atribuir por referência não é apenas limitado a variáveis e matrizes, eles também
estão presentes para funções e todas
3112 referência associações
3113 function incrementArray (& $arr) {
3114 foreach ($arr as & $val) {
3115 $val ++;
3116 }
3117 }
3118 function & getArray () {
3119 static $arr = [1, 2, 3];
3120 return $arr;
3121 }
3122 incrementArray (getArray ());
3123 var_dump (getArray ()); //imprime uma matriz [2, 3, 4]
3124 Atribuição é a chave dentro da definição da função como acima Você não pode passar
uma expressão por referência, apenas um
3125 valor /variável Daí a instanciação de $a em bar ().
3126 Seção 11.2: Retorno por Referência
3127 Ocasionalmente chega a hora de você implicitamente retornar por referência
3128 Retornar por referência é útil quando você quer usar uma função para encontrar a
qual variável uma referência
3129 deve ser ligado Não use retorno por referência para aumentar o desempenho O motor
irá automaticamente
3130 otimize isso por conta própria Somente retorne referências quando você tiver uma
razão técnica válida para isso.
3131 FF
3132 Notas PHP para Profissionais 68
3133 Extraído da documentação do PHP para retorno por referência
3134 Existem muitos formulários diferentes que o retorno por referência pode levar,
incluindo o seguinte exemplo:
3135 função pai (& $var) {
3136 echo $var;
3137 $var = "updated";
3138 }
3139 function & child () {
3140 static $a = "teste";
3141 devolve $a;
3142 }
3143 pai (filho ()); //retorna "teste"
3144 pai (filho ()); //retorna "atualizado"
3145 Retornar por referência não se limita apenas às referências de função Você também
tem a capacidade de chamar implicitamente a função:
3146 function & myFunction () {
3147 static $a = 'foo';
3148 devolve $a;
3149 }
3150 $bar = & myFunction ();
3151 $bar = "atualizado"
3152 echo myFunction ();
3153 Você não pode referenciar diretamente uma chamada de função, ela deve ser atribuída
a uma variável antes de aproveitála Para ver como isso
3154 funciona, simplesmente tente echo & myFunction ();
3155 Notas
3156 Você é obrigado a especificar uma referência (&) nos dois locais em que pretende
usála Isso significa que, para o seu
3157 definição de função (função & myFunction () {...) e na referência de chamada (função
3158 callFunction (& $variable) {.ou & myFunction ();)
3159 Você só pode retornar uma variável por referência Daí a instanciação de $a no
exemplo acima Isso significa
3160 você não pode retornar uma expressão, caso contrário, um erro PHP E_NOTICE será
gerado (Aviso: Apenas
3161 referências variáveis devem ser retornadas por referência em ..)
3162 O retorno por referência tem casos de uso legítimos, mas devo avisar que eles devem
ser usados com moderação,
3163 somente depois de explorar todas as outras opções possíveis para alcançar o mesmo
objetivo
3164 Seção 11.3: Passe por referência
3165 Isso permite que você passe uma variável por referência a uma função ou elemento que
permite modificar o original
3166 variável
3167 A passagem por referência não se limita apenas às variáveis, o seguinte também pode
ser passado por referência:
3168 Novas declarações, por exemplo, foo (new SomeClass)
3169 Referências retornadas de funções
3170 Matrizes
3171 Um uso comum de "passagem por referência" é modificar os valores iniciais dentro de
um array sem ir até o ponto de
3172 FF
3173 Notas PHP para Profissionais 69
3174 criando novos arrays ou sujando seu namespace A passagem por referência é tão
simples quanto preceder /prefixar o
3175 variável com um & => & $myElement
3176 Abaixo está um exemplo de aproveitar um elemento de um array e simplesmente
adicionar 1 ao seu valor inicial
3177 $arr = array (1, 2, 3, 4, 5);
3178 foreach ($arr as & $num) {
3179 $num ++;
3180 }
3181 Agora, quando você aproveitar qualquer elemento dentro de $arr, o elemento original
será atualizado, pois a referência foi
3182 aumentou Você pode verificar isso por:
3183 print_r ($arr);
3184 Nota
3185 Você deve tomar nota quando aproveitar passando por referência dentro de loops No
final do loop acima, $num
3186 ainda contém uma referência ao último elemento da matriz Atribuir isso postar loop
vai acabar manipulando o
3187 último elemento da matriz! Você pode garantir que isso não aconteça com unset ()
colocandoo no pósloop:
3188 $myArray = array (1, 2, 3, 4, 5);
3189 foreach ($myArray como & $num) {
3190 $num ++;
3191 }
3192 unset ($num);
3193 O acima irá garantir que você não tenha problemas Um exemplo de problemas que podem
se relacionar com isso é
3194 presente nesta pergunta no StackOverflow
3195 Funções
3196 Outro uso comum para passagem por referência está dentro das funções Modificar a
variável original é tão simples quanto:
3197 $var = 5;
3198 //definir
3199 function add (& $var) {
3200 $var ++;
3201 }
3202 //ligar
3203 add ($var);
3204 O que pode ser verificado fazendo eco da variável original
3205 echo $var;
3206 Existem várias restrições em torno das funções, conforme indicado abaixo nos
documentos do PHP:
3207 Nota: Não há sinal de referência em uma chamada de função apenas nas definições de
função Definições de função
3208 sozinhos são suficientes para passar corretamente o argumento por referência A
partir do PHP 5.3.0, você receberá um aviso
3209 FF
3210 Notas PHP para Profissionais 70
3211 dizendo que o "tempo de chamada por referência" é obsoleto quando você usa o & in
foo (& $a) ; E a partir do PHP 5.4.0,
3212 o tempo de chamada passagem por referência foi removido, portanto, usálo gerará um
erro fatal.
3213 FF
3214 Notas PHP para Profissionais 71
3215 Capítulo 12: Matrizes
3216 Detalhe do Parâmetro
3217 Chave A chave é o identificador e o índice exclusivos de uma matriz Pode ser uma
string ou um inteiro Assim sendo,
3218 chaves válidas seriam 'foo', '5', 10, 'a2b', .
3219 Valor Para cada chave existe um valor correspondente (null caso contrário e um aviso
é emitido após o acesso) o
3220 valor não tem restrições sobre o tipo de entrada
3221 Uma matriz é uma estrutura de dados que armazena um número arbitrário de valores em
um único valor Um array em PHP é na verdade um
3222 mapa ordenado, em que map é um tipo que associa valores a chaves
3223 Seção 12.1: inicializando uma matriz
3224 Uma matriz pode ser inicializada vazia:
3225 //Uma matriz vazia
3226 $foo = array ();
3227 //Notação de taquigrafia disponível desde o PHP 5.4
3228 $foo = [];
3229 Uma matriz pode ser inicializada e predefinida com valores:
3230 //Cria um array simples com três strings
3231 $fruit = array ('maçãs', 'pêras', 'laranjas');
3232 //Notação de taquigrafia disponível desde o PHP 5.4
3233 $fruit = ['apples', 'peras', 'laranjas'];
3234 Um array também pode ser inicializado com índices personalizados (também chamados de
array associativo):
3235 //Um array associativo simples
3236 $fruit = array (
3237 'primeiro' => 'maçãs',
3238 'segundo' => 'peras',
3239 'terceiro' => 'laranjas'
3240 );
3241 //Key e value também podem ser definidos da seguinte forma
3242 $fruit ['first'] = 'maçãs';
3243 //Notação de taquigrafia disponível desde o PHP 5.4
3244 $fruit = [
3245 'primeiro' => 'maçãs',
3246 'segundo' => 'peras',
3247 'terceiro' => 'laranjas'
3248 ];
3249 Se a variável não foi usada antes, o PHP irá criála automaticamente Embora
conveniente, isso pode tornar o código
3250 mais difícil de ler:
3251 $foo [] = 1; //Array ([0] => 1)
3252 FF
3253 Notas PHP para Profissionais 72
3254 $bar [] [] = 2; //Array ([0] => Array ([0] => 2))
3255 O índice geralmente continua de onde você parou O PHP tentará usar strings numéricas
como inteiros:
3256 $foo = [2 => 'maça', 'melão']; //Matriz ([2] => maçã, [3] => melão)
3257 $foo = ['2' => 'maçã', 'melão']; //o mesmo que acima
3258 $foo = [2 => 'apple', 'este é o índice 3 temporariamente', '3' => 'melão']; //o
mesmo que acima! O último
3259 a entrada sobrescreve a segunda!
3260 Para inicializar uma matriz com tamanho fixo, você pode usar SplFixedArray:
3261 $array = new SplFixedArray (3);
3262 $array [0] = 1;
3263 $array [1] = 2;
3264 $array [2] = 3;
3265 $array [3] = 4; //Exceção de tempo de execução
3266 //Aumenta o tamanho do array para 10
3267 $array> setSize (10);
3268 Nota: Uma matriz criada usando SplFixedArray tem um consumo de memória reduzido para
grandes conjuntos de dados, mas as chaves
3269 deve ser inteiros
3270 Para inicializar uma matriz com um tamanho dinâmico, mas com n elementos não vazios
(por exemplo, um espaço reservado), você pode usar um loop como
3271 segue:
3272 $myArray = array ();
3273 $sizeOfMyArray = 5;
3274 $fill = 'espaço reservado';
3275 para ($i = 0; $i <$sizeOfMyArray; $i ++) {
3276 $myArray [] = $preenchimento;
3277 }
3278 //print_r ($myArray); resulta no seguinte:
3279 //Array ([0] => espaço reservado [1] => espaço reservado [2] => espaço reservado [3]
=> espaço reservado [4] =>
3280 placeholder)
3281 Se todos os espaços reservados forem iguais, você também poderá criálo usando a
função array_fill ():
3282 array array_fill (int $start_index, int $num, misto $valor)
3283 Isso cria e retorna uma matriz com entradas numéricas de valor, chaves iniciando em
start_index
3284 Nota: Se o start_index for negativo, ele começará com o índice negativo e continuará
a partir de 0 para o seguinte
3285 elementos
3286 $a = array_fill (5, 6, 'banana'); //Array ([5] => banana, [6] => banana, ..., [10]
=> banana)
3287 $b = array_fill (2, 4, 'pêra'); //Array ([2] => pear, [0] => pear, ..., [2] => pear)
3288 Conclusão: Com array_fill () você é mais limitado para o que você pode realmente
fazer O loop é mais flexível e
3289 FF
3290 Notas PHP para Profissionais 73
3291 abre uma ampla gama de oportunidades
3292 Sempre que você quiser uma matriz preenchida com um intervalo de números (por
exemplo, 14), você pode anexar todos os elementos
3293 para uma matriz ou use a função range ():
3294 intervalo de matriz (misto $start, misto $end [, number $step = 1])
3295 Essa função cria uma matriz contendo um intervalo de elementos Os dois primeiros
parâmetros são necessários, onde
3296 defina os pontos inicial e final do intervalo (inclusive) O terceiro parâmetro é
opcional e define o tamanho do
3297 passos a serem dados Criando um intervalo de 0 a 4 com um tamanho de etapa de 1, o
array resultante consistiria no
3298 seguintes elementos: 0, 1, 2, 3 e 4 Se o tamanho do passo for aumentado para 2 (ou
seja, intervalo (0, 4, 2)), a matriz resultante
3299 seria: 0, 2 e 4
3300 $array = [];
3301 $array_with_range = intervalo (1, 4);
3302 para ($i = 1; $i <= 4; $i ++) {
3303 $array [] = $i;
3304 }
3305 print_r ($array); //Matriz ([0] => 1 [1] => 2 [2] => 3 [3] => 4)
3306 print_r ($array_with_range); //Matriz ([0] => 1 [1] => 2 [2] => 3 [3] => 4)
3307 O intervalo pode funcionar com números inteiros, flutuantes, booleanos (que são
convertidos em inteiros) e strings O cuidado deve ser
3308 tomadas, no entanto, ao usar floats como argumentos devido ao problema de precisão
de ponto flutuante
3309 Seção 12.2: Verificar se existe chave
3310 Use array_key_exists () ou isset () ou! Empty ():
3311 $map = [
3312 'foo' => 1,
3313 'barra' => nulo,
3314 'foobar' => '',
3315 ];
3316 array_key_exists ('foo', $map); //verdade
3317 isset ($map ['foo']); //verdade
3318 vazio ($map ['foo']); //verdade
3319 array_key_exists ('bar', $map); //verdade
3320 isset ($map ['bar']); //false
3321 vazio ($map ['bar']); //false
3322 Note que isset () trata um elemento com valor nulo como inexistente Considerando que
o empty () faz o mesmo para qualquer elemento
3323 Isso é igual a false (usando uma comparação fraca; por exemplo, null, '' e 0 são
todos tratados como false por! empty ())
3324 Enquanto isset ($map ['foobar']); é verdade! vazio ($map ['foobar']) é falso Isso
pode levar a erros (por exemplo,
3325 é fácil esquecer que a string '0' é tratada como falsa), então o uso de! empty () é
freqüentemente desaprovado
3326 Note também que isset () e! Empty () funcionarão (e retornarão false) se $map não
estiver definido Isso os torna
3327 um pouco propenso a erros para usar:
3328 //Anote "long" vs "lang", um pequeno erro no nome da variável
3329 $my_array_with_a_long_name = ['foo' => verdadeiro];
3330 array_key_exists ('foo', $my_array_with_a_lang_name); //mostra um aviso
3331 isset ($my_array_with_a_lang_name ['foo']); //retorna falso
3332 FF
3333 Notas PHP para Profissionais 74
3334 Você também pode verificar as matrizes ordinais:
3335 $ord = ['a', 'b']; //equivalente a [0 => 'a', 1 => 'b']
3336 array_key_exists (0, $ord); //verdade
3337 array_key_exists (2, $ord); //false
3338 Note que isset () tem melhor desempenho do que array_key_exists () como o último é
uma função e o primeiro
3339 construção de linguagem
3340 Você também pode usar key_exists (), que é um alias para array_key_exists ()
3341 Seção 12.3: Validando o tipo de array
3342 A função is_array () retorna true se uma variável é uma matriz
3343 $inteiro = 1337;
3344 $array = [1337, 42];
3345 is_array ($integer); //false
3346 is_array ($array); //verdade
3347 Você pode digitar a dica do tipo de matriz em uma função para impor um tipo de
parâmetro; passar qualquer outra coisa resultará em um fatal
3348 erro
3349 função foo (matriz $array) {/* $array é uma matriz */}
3350 Você também pode usar a função gettype ()
3351 $inteiro = 1337;
3352 $array = [1337, 42];
3353 gettype ($integer) === 'array'; //false
3354 gettype ($array) === 'array'; //verdade
3355 Seção 12.4: Criando uma matriz de variáveis
3356 $username = 'Hadibut';
3357 $email = 'hadibut@example.org';
3358 $variables = compact ('username', 'email');
3359 //$variables é agora ['username' => 'Hadibut', 'email' => 'hadibut@example.org']
3360 Este método é freqüentemente usado em frameworks para passar um array de variáveis
entre dois componentes
3361 Seção 12.5: Verificando se existe um valor no array
3362 A função in_array () retorna true se um item existir em uma matriz
3363 $fruits = ['banana', 'maçã'];
3364 $foo = in_array ('banana', $frutas);
3365 O valor de //$foo é verdadeiro
3366 $bar = in_array ('laranja', $frutas);
3367 FF
3368 Notas PHP para Profissionais 75
3369 //$bar valor é falso
3370 Você também pode usar a função array_search () para obter a chave de um item
específico em uma matriz
3371 $userdb = ['Sandra Shush', 'Stefanie Mcmohn', 'Michael'];
3372 $pos = array_search ('Stefanie Mcmohn', $userdb);
3373 if ($pos! == false) {
3374 eco "Stefanie Mcmohn encontrado em $pos";
3375 }
3376 Versão do PHP 5.x = 5.5
3377 No PHP 5.5 e posterior, você pode usar array_column () em conjunto com array_search
()
3378 Isso é particularmente útil para verificar se existe um valor em uma matriz
associativa:
3379 $userdb = [
3380 [
3381 "uid" => '100',
3382 "name" => 'Sandra Shush',
3383 "url" => 'urlof100',
3384 ]
3385 [
3386 "uid" => '5465',
3387 "name" => 'Stefanie Mcmohn',
3388 "pic_square" => 'urlof100',
3389 ]
3390 [
3391 "uid" => '40489',
3392 "name" => 'Michael',
3393 "pic_square" => 'urlof40489',
3394 ]
3395 ];
3396 $key = array_search (40489, array_column ($userdb, 'uid'));
3397 Seção 12.6: Interfaces ArrayAccess e Iterator
3398 Outro recurso útil é acessar suas coleções de objetos personalizados como matrizes
no PHP Existem duas interfaces
3399 disponível no PHP (> = 5.0.0) core para suportar isto: ArrayAccess e Iterator O
primeiro permite que você acesse seu
3400 objetos personalizados como matriz
3401 ArrayAccess
3402 Suponha que temos uma classe de usuário e uma tabela de banco de dados armazenando
todos os usuários Nós gostaríamos de criar uma UserCollection
3403 classe que irá:
3404 1 permitirnos resolver determinado usuário pelo seu identificador único nome de
usuário
3405 2 executar operações básicas (não todas CRUD, mas pelo menos Criar, Recuperar e
Excluir) em nossa coleção de usuários
3406 Considere a seguinte fonte (de agora em diante estamos usando a sintaxe de criação
de matriz curta [] disponível desde a versão 5.4):
3407 classe UserCollection implementa ArrayAccess {
3408 protegido $_conn;
3409 protected $_requiredParams = ['username', 'password', 'email'];
3410 função pública __construct () {
3411 $config = new Configuração ();
3412 FF
3413 Notas PHP para Profissionais 76
3414 $connectionParams = [
3415 //sua conexão com o banco de dados
3416 ];
3417 $this > _ conn = DriverManager :: getConnection ($connectionParams, $config);
3418 }
3419 função protegida _getByUsername ($username) {
3420 $ret = $this > _ conn> executeQuery ('SELECT * FROM `Usuário` WHERE` username` IN
(?)',
3421 [$username]
3422 ) > buscar ();
3423 return $ret;
3424 }
3425 //START dos métodos requeridos pela interface ArrayAccess
3426 função pública offsetExists ($offset) {
3427 return (bool) $this > _ getByUsername (deslocamento de $);
3428 }
3429 função pública offsetGet ($offset) {
3430 return $this > _ getByUsername ($offset);
3431 }
3432 função pública offsetSet ($offset, $value) {
3433 if (! is_array ($value)) {
3434 lançar novo \ Exception ('value must be an Array');
3435 }
3436 $passed = array_intersect (array_values ($this > _ requiredParams), array_keys
($value));
3437 if (count ($passado) <count ($this > _ requiredParams)) {
3438 throw new \ Exception ('o valor deve conter pelo menos os seguintes parâmetros:'
3439 implode (',', $this > _ requiredParams));
3440 }
3441 $this > _ conn> insert ('Usuário', $valor);
3442 }
3443 função pública offsetUnset ($offset) {
3444 if (! is_string ($offset)) {
3445 throw new \ Exception ('valor deve ser o nome de usuário para deletar');
3446 }
3447 if (! $this> offsetGet ($offset)) {
3448 throw new \ Exception ('usuário não encontrado');
3449 }
3450 $this > _ conn> delete ('Usuário', ['username' => $offset]);
3451 }
3452 //END dos métodos requeridos pela interface ArrayAccess
3453 }
3454 então nós podemos:
3455 $users = new UserCollection ();
3456 var_dump (vazio ($users ['testuser']), isset ($usuários ['testuser']));
3457 $users ['testuser'] = ['username' => 'testuser',
3458 'password' => 'testpassword',
3459 'email' => 'test@test.com'];
3460 var_dump (vazio ($users ['testuser']), isset ($usuários ['testuser']), $users
['testuser']);
3461 unset ($users ['testuser']);
3462 var_dump (vazio ($users ['testuser']), isset ($usuários ['testuser']));
3463 FF
3464 Notas PHP para Profissionais 77
3465 que produzirá o seguinte, assumindo que não houve testuser antes de lançarmos o
código:
3466 bool (verdadeiro)
3467 bool (falso)
3468 bool (falso)
3469 bool (verdadeiro)
3470 array (17) {
3471 ["username"] =>
3472 string (8) "testuser"
3473 ["senha"] =>
3474 string (12) "testpassword"
3475 ["email"] =>
3476 string (13) "test@test.com"
3477 }
3478 bool (verdadeiro)
3479 bool (falso)
3480 IMPORTANTE: offsetExists não é chamado quando você verifica a existência de uma
chave com a função array_key_exists Então o
3481 o código a seguir produzirá uma saída falsa duas vezes:
3482 var_dump (array_key_exists ('testuser', $users));
3483 $users ['testuser'] = ['username' => 'testuser',
3484 'password' => 'testpassword',
3485 'email' => 'test@test.com'];
3486 var_dump (array_key_exists ('testuser', $users));
3487 Iterador
3488 Vamos estender nossa classe de cima com algumas funções da interface Iterator para
permitir iterar sobre ela com
3489 foreach e while
3490 Primeiro, precisamos adicionar uma propriedade contendo nosso índice atual de
iterador, vamos adicionála às propriedades da classe como
3491 $_position:
3492 //posição atual do iterador, requerida pelos métodos da interface Iterator
3493 protected $_position = 1;
3494 Em segundo lugar, vamos adicionar a interface Iterator à lista de interfaces que
estão sendo implementadas pela nossa classe:
3495 classe UserCollection implementa ArrayAccess, Iterator {
3496 em seguida, adicione o requerido pelas próprias funções da interface:
3497 //START dos métodos requeridos pela interface Iterator
3498 public function current () {
3499 return $this > _ getById ($this > _ posição);
3500 }
3501 chave de função pública () {
3502 retorne $this > _ posição;
3503 }
3504 função pública next () {
3505 $this > _ posição ++;
3506 }
3507 função pública rewind () {
3508 $this > _ posição = 1;
3509 }
3510 função pública valid () {
3511 return null! == $this > _ getById ($this > posição);
3512 FF
3513 Notas PHP para Profissionais 78
3514 }
3515 //END dos métodos exigidos pela interface Iterator
3516 Então, tudo em tudo aqui é fonte completa da classe implementando ambas as
interfaces Note que este exemplo não é perfeito
3517 porque os IDs no banco de dados podem não ser sequenciais, mas isso foi escrito
apenas para dar a idéia principal: você pode
3518 abordar suas coleções de objetos de qualquer maneira, implementando interfaces
ArrayAccess e Iterator:
3519 classe UserCollection implementa ArrayAccess, Iterator {
3520 //posição atual do iterador, requerida pelos métodos da interface Iterator
3521 protected $_position = 1;
3522 //<adicione os métodos antigos do último snippet de código aqui>
3523 //START dos métodos requeridos pela interface Iterator
3524 public function current () {
3525 return $this > _ getById ($this > _ posição);
3526 }
3527 chave de função pública () {
3528 retorne $this > _ posição;
3529 }
3530 função pública next () {
3531 $this > _ posição ++;
3532 }
3533 função pública rewind () {
3534 $this > _ posição = 1;
3535 }
3536 função pública valid () {
3537 return null! == $this > _ getById ($this > posição);
3538 }
3539 //END dos métodos exigidos pela interface Iterator
3540 }
3541 e um loop foreach através de todos os objetos do usuário:
3542 foreach ($users as $user) {
3543 var_dump ($user ['id']);
3544 }
3545 que irá produzir algo como
3546 string (2) "1"
3547 string (2) "2"
3548 string (2) "3"
3549 string (2) "4"
3550 ...
3551 FF
3552 Notas PHP para Profissionais 79
3553 Capítulo 13: Iteração de Matriz
3554 Seção 13.1: Iterando vários arrays juntos
3555 Às vezes, duas matrizes do mesmo comprimento precisam ser iteradas juntas, por
exemplo:
3556 $people = ['Tim', 'Tony', 'Turanga'];
3557 $foods = ['chicken', 'beef', 'slurm'];
3558 array_map é a maneira mais simples de fazer isso:
3559 array_map (função ($person, $food) {
3560 return "$pessoa gosta de $food \ n";
3561 }, $pessoas, $foods);
3562 qual produzirá:
3563 Tim gosta de frango
3564 Tony gosta de carne
3565 Turanga gosta de slurm
3566 Isso pode ser feito através de um índice comum:
3567 assert (count ($pessoas) === count ($foods));
3568 para ($i = 0; $i <count ($pessoas); $i ++) {
3569 echo "$people [$i] gosta de $foods [$i] \ n";
3570 }
3571 Se as duas matrizes não tiverem as chaves incrementais, array_values ($array) [$i]
pode ser usado para substituir $array [$i]
3572 Se os dois arrays tiverem a mesma ordem de chaves, você também pode usar um loop
foreachwithkey em um dos arrays:
3573 foreach ($people as $index => $person) {
3574 $food = $foods [$index];
3575 echo "$person gosta de $food \ n";
3576 }
3577 Matrizes separadas só podem ser passadas por loop se tiverem o mesmo comprimento e
também tiverem o mesmo nome de chave este
3578 significa que se você não fornecer uma chave e eles forem numerados, você ficará
bem, ou se nomear as chaves e colocálas em
3579 a mesma ordem em cada array
3580 Você também pode usar array_combine
3581 $combinedArray = array_combine ($pessoas, $foods);
3582 //$combinedArray = ['Tim' => 'frango', 'Tony' => 'beef', 'Turanga' => 'slurm'];
3583 Então você pode percorrer isso fazendo o mesmo que antes:
3584 foreach ($combinedArray como $person => $meal) {
3585 echo "$pessoa gosta de $refeição \ n";
3586 }
3587 FF
3588 Notas PHP para Profissionais 80
3589 Seção 13.2: Usando um índice incremental
3590 Esse método funciona incrementando um inteiro de 0 para o maior índice da matriz
3591 $colors = ['vermelho', 'amarelo', 'azul', 'verde'];
3592 para ($i = 0; $i <count ($colors); $i ++) {
3593 eco 'eu sou a cor' $colors [$i] '<br>';
3594 }
3595 Isso também permite iterar um array em ordem reversa sem usar array_reverse, o que
pode resultar em sobrecarga se
3596 a matriz é grande
3597 $colors = ['vermelho', 'amarelo', 'azul', 'verde'];
3598 para ($i = count ($colors) 1; $i> = 0; $i) {
3599 eco 'eu sou a cor' $colors [$i] '<br>';
3600 }
3601 Você pode pular ou rebobinar o índice facilmente usando este método
3602 $array = ["alpha", "beta", "gamma", "delta", "epsilon"];
3603 para ($i = 0; $i <count ($array); $i ++) {
3604 echo $array [$i], PHP_EOL;
3605 if ($array [$i] === "gamma") {
3606 $array [$i] = "zeta";
3607 $i = 2;
3608 } elseif ($array [$i] === "zeta") {
3609 $i ++;
3610 }
3611 }
3612 Saída:
3613 alfa
3614 beta
3615 gama
3616 beta
3617 zeta
3618 épsilon
3619 Para matrizes que não possuem índices incrementais (incluindo matrizes com índices
na ordem inversa, por exemplo, [1 => "foo", 0
3620 => "bar"], ["foo" => "f", "bar" => "b"]), isso não pode ser feito diretamente
array_values ou array_keys podem ser
3621 usado em vez disso:
3622 $array = ["a" => "alfa", "b" => "beta", "c" => "gamma", "d" => "delta"];
3623 $keys = array_keys ($array);
3624 para ($i = 0; $i <count ($array); $i ++) {
3625 $key = $keys [$i];
3626 $value = $array [$key];
3627 echo "$value é $key \ n";
3628 }
3629 Seção 13.3: Usando ponteiros da matriz interna
3630 Cada instância da matriz contém um ponteiro interno Manipulando este ponteiro,
diferentes elementos de um array podem ser
3631 recuperado da mesma chamada em momentos diferentes
3632 Usando cada
3633 FF
3634 Notas PHP para Profissionais 81
3635 Cada chamada para cada () retorna a chave e o valor do elemento da matriz atual e
incrementa a matriz interna
3636 ponteiro
3637 $array = ["f" => "foo", "b" => "barra"];
3638 while (list ($key, $value) = cada um ($array)) {
3639 echo "$value começa com $key";
3640 }
3641 Usando o próximo
3642 $array = ["Alfa", "Beta", "Gama", "Delta"];
3643 while (($value = next ($array))! == false) {
3644 echo "$value \ n";
3645 }
3646 Note que este exemplo assume que nenhum elemento no array é idêntico ao booleano
false Para evitar tais
3647 suposição, use a chave para verificar se o ponteiro interno atingiu o final da
matriz:
3648 $array = ["Alfa", "Beta", "Gama", "Delta"];
3649 while (chave ($array)! == null) {
3650 eco atual ($array) PHP_EOL;
3651 next ($array);
3652 }
3653 Isso também facilita a repetição de uma matriz sem um loop direto:
3654 class ColorPicker {
3655 private $colors = ["# FF0064", "# 0064FF", "# 64FF00", "# FF6400", "# 00FF64", "#
6400FF"];
3656 Função pública nextColor (): string {
3657 $result = next ($colors);
3658 //se o fim do array for atingido
3659 if (chave ($colors) === null) {
3660 redefinir ($cores);
3661 }
3662 return $result;
3663 }
3664 }
3665 Seção 13.4: Usando o foreach
3666 Loop direto
3667 foreach ($colors as $color) {
3668 echo "Eu sou a cor $color <br>";
3669 }
3670 Loop com chaves
3671 $foods = ['healthy' => 'Maçãs', 'bad' => 'Sorvete'];
3672 foreach ($foods como $key => $food) {
3673 eco "Comer $comida é $chave";
3674 }
3675 Loop por referência
3676 Nos loops foreach nos exemplos acima, modificar o valor ($color ou $food)
diretamente não altera seu valor
3677 na matriz O operador & é necessário para que o valor seja um ponteiro de referência
para o elemento na matriz.
3678 $years = [2001, 2002, 3, 4];
3679 foreach ($anos como & $ano) {
3680 if ($ano <2000) $ano + = 2000;
3681 FF
3682 Notas PHP para Profissionais 82
3683 }
3684 Isso é semelhante a:
3685 $years = [2001, 2002, 3, 4];
3686 para ($i = 0; $i <count ($anos); $i ++) {//estas duas linhas
3687 $year = & $years [$i]; //são alterados para foreach por referência
3688 if ($ano <2000) $ano + = 2000;
3689 }
3690 Concorrência
3691 Matrizes PHP podem ser modificadas de qualquer maneira durante a iteração sem
problemas de simultaneidade (diferentemente de listas de Java, por exemplo) E se
3692 a matriz é iterada por referência, as iterações posteriores serão afetadas por
alterações na matriz Caso contrário, as alterações em
3693 a matriz não afetará as iterações posteriores (como se você estivesse iterando uma
cópia da matriz) Compare o loop por
3694 valor:
3695 $array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
3696 foreach ($array como $key => $value) {
3697 if ($key === 0) {
3698 $array [6] = 17;
3699 unset ($array [4]);
3700 }
3701 echo "$key => $valor \ n";
3702 }
3703 Saída:
3704 0 => 1
3705 2 => 3
3706 4 => 5
3707 6 => 7
3708 Mas se a matriz é iterada com referência,
3709 $array = [0 => 1, 2 => 3, 4 => 5, 6 => 7];
3710 foreach ($array como $key => & $value) {
3711 if ($key === 0) {
3712 $array [6] = 17;
3713 unset ($array [4]);
3714 }
3715 echo "$key => $valor \ n";
3716 }
3717 Saída:
3718 0 => 1
3719 2 => 3
3720 6 => 17
3721 O conjunto de valoreschave de 4 => 5 não é mais iterado e 6 => 7 é alterado para 6
=> 17.
3722 FF
3723 Notas PHP para Profissionais 83
3724 Seção 13.5: Usando o Iterador ArrayObject
3725 Php arrayiterator permite que você modifique e desmarque os valores enquanto itera
sobre arrays e objetos
3726 Exemplo:
3727 $array = ['1' => 'apple', '2' => 'banana', '3' => 'cereja'];
3728 $arrayObject = new ArrayObject ($array);
3729 $iterator = $arrayObject> getIterator ();
3730 para ($iterator; $iterator> valid (); $iterator> next ()) {
3731 echo $iterator> key () '=>' $iterator> atual () "</br>";
3732 }
3733 Saída:
3734 1 => maçã
3735 2 => banana
3736 3 => cereja
3737 FF
3738 Notas PHP para Profissionais 84
3739 Capítulo 14: Executando em uma matriz
3740 Seção 14.1: Aplicando uma função para cada elemento de um array
3741 Para aplicar uma função a todos os itens de uma matriz, use array_map () Isso
retornará uma nova matriz.
3742 $array = array (1,2,3,4,5);
3743 //cada item da matriz é iterado e armazenado no parâmetro da função
3744 $newArray = array_map (function ($item) {
3745 devolve $item + 1;
3746 }, $array);
3747 $newArray agora é array (2,3,4,5,6);
3748 Em vez de usar uma função anônima, você poderia usar uma função nomeada O acima pode
ser escrito como:
3749 function addOne ($item) {
3750 devolve $item + 1;
3751 }
3752 $array = array (1, 2, 3, 4, 5);
3753 $newArray = array_map ('addOne', $array);
3754 Se a função nomeada for um método de classe, a chamada da função deve incluir uma
referência a um objeto de classe
3755 método pertence a:
3756 class Example {
3757 public function addOne ($item) {
3758 devolve $item + 1;
3759 }
3760 função pública doCalculation () {
3761 $array = array (1, 2, 3, 4, 5);
3762 $newArray = array_map (array ($this, 'addOne'), $array);
3763 }
3764 }
3765 Outra maneira de aplicar uma função a cada item em uma matriz é array_walk () e
array_walk_recursive () o
3766 retorno de chamada passado para essas funções leva a chave /índice e valor de cada
item da matriz Essas funções não
3767 retorna um novo array, em vez de um booleano para o sucesso Por exemplo, para
imprimir todos os elementos em uma matriz simples:
3768 $array = array (1, 2, 3, 4, 5);
3769 array_walk ($array, função ($value, $key) {
3770 echo $value '';
3771 });
3772 //imprime "1 2 3 4 5"
3773 O parâmetro valor do callback pode ser passado por referência, permitindo que você
altere o valor diretamente no
3774 matriz original:
3775 $array = array (1, 2, 3, 4, 5);
3776 array_walk ($array, função (& $value, $key) {
3777 $value ++;
3778 });
3779 $array agora é array (2,3,4,5,6);
3780 FF
3781 Notas PHP para Profissionais 85
3782 Para matrizes aninhadas, array_walk_recursive () vai mais fundo em cada subarray:
3783 $array = array (1, array (2, 3, array (4, 5), 6);
3784 array_walk_recursive ($array, função ($value, $key) {
3785 echo $value '';
3786 });
3787 //imprime "1 2 3 4 5 6"
3788 Nota: array_walk e array_walk_recursive permitem alterar o valor dos itens da
matriz, mas não as chaves Passando o
3789 chaves por referência no retorno de chamada é válido, mas não tem efeito
3790 Seção 14.2: dividir array em partes
3791 array_chunk () divide uma matriz em pedaços
3792 Digamos que estamos seguindo uma matriz dimensional única
3793 $input_array = array ('a', 'b', 'c', 'd', 'e');
3794 Agora usando array_chunk () no array PHP acima,
3795 $output_array = array_chunk ($input_array, 2);
3796 O código acima fará pedaços de 2 elementos da matriz e criará uma matriz
multidimensional da seguinte forma
3797 Matriz
3798 (
3799 [0] => Matriz
3800 (
3801 [0] => a
3802 [1] => b
3803 )
3804 [1] => Matriz
3805 (
3806 [0] => c
3807 [1] => d
3808 )
3809 [2] => Matriz
3810 (
3811 [0] => e
3812 )
3813 )
3814 Se todos os elementos da matriz não forem divididos uniformemente pelo tamanho do
bloco, o último elemento da matriz de saída será
3815 elementos restantes
3816 Se passarmos o segundo argumento como menor que 1, então E_WARNING será lançado e a
matriz de saída será NULL
3817 Detalhes do Parâmetro
3818 $array (array) Matriz de entrada, o array para trabalhar
3819 $size (int) Tamanho de cada pedaço (valor inteiro)
3820 $preserve_keys (boolean) (opcional) Se você deseja que a matriz de saída preserve as
chaves, definaa para TRUE, caso contrário, FALSE.
3821 FF
3822 Notas PHP para Profissionais 86
3823 Seção 14.3: Implodindo uma matriz em string
3824 implode () combina todos os valores da matriz, mas perde toda a informação chave:
3825 $arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"];
3826 echo implode ("", $arr); //AA BB CC
3827 A implementação de chaves pode ser feita usando a chamada array_keys ():
3828 $arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"];
3829 echo implode ("", array_keys ($arr)); //abc
3830 A implementação de chaves com valores é mais complexa, mas pode ser feita usando o
estilo funcional:
3831 $arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"];
3832 echo implode ("", array_map (função ($key, $val) {
3833 return "$chave: $val"; //função que cola a chave para o valor
3834 }, array_keys ($arr), $arr));
3835 //Saída: a: AA b: BB c: CC
3836 Seção 14.4: Matrizes "Destructuring" usando list ()
3837 Use list () para atribuir rapidamente uma lista de valores de variáveis em uma
matriz Veja também compact ()
3838 //Atribui a $a, $be $c os valores de seus respectivos elementos de array em $array
com
3839 chaves numeradas de zero
3840 lista ($a, $b, $c) = $array;
3841 Com o PHP 7.1 (atualmente em beta) você poderá usar a sintaxe da lista curta:
3842 //Atribui a $a, $be $c os valores de seus respectivos elementos de matriz em $array
com chaves
3843 numerado de zero
3844 [$a, $b, $c] = $array;
3845 //Atribui a $a, $be $c os valores dos elementos da matriz em $array com as chaves
"a", "b" e
3846 "c", respectivamente
3847 ["a" => $a, "b" => $b, "c" => $c] = $array;
3848 Seção 14.5: array_reduce
3849 array_reduce reduz o array em um valor único Basicamente, o array_reduce vai passar
por todos os itens com o
3850 resultado da última iteração e produzir novo valor para a próxima iteração
3851 Uso: array_reduce ($array, função ($carry, $item) {...},
$defaul_value_of_first_carry)
3852 $carry é o resultado da última rodada de iteração
3853 $item é o valor da posição atual na matriz
3854 Soma do array
3855 $result = array_reduce ([1, 2, 3, 4, 5], função ($carry, $item) {
3856 return $carry + $item;
3857 FF
3858 Notas PHP para Profissionais 87
3859 });
3860 Resultado: 15
3861 O maior número na matriz
3862 $result = array_reduce ([10, 23, 211, 34, 25], função ($carry, $item) {
3863 devolver $item> $transportar? $item: $carry;
3864 });
3865 Resultado: 211
3866 É todo o item mais de 100
3867 $result = array_reduce ([101, 230, 210, 341, 251], função ($carry, $item) {
3868 devolve $carry && $item> 100;
3869 }, verdade); //o valor padrão deve ser definido como verdadeiro
3870 resultado: true
3871 Qualquer item menor que 100?
3872 $result = array_reduce ([101, 230, 21, 341, 251], função ($carry, $item) {
3873 devolve $carreg || $item <100;
3874 }, false); //o valor padrão deve definir false
3875 resultado: true
3876 Como implodir ($array, $piece)
3877 $result = array_reduce (["olá", "mundo", "PHP", "idioma"], função ($carry, $item) {
3878 devolver! $carregar? $item: $transportar "" $item;
3879 });
3880 resultado: "helloworldlinguagem PHP"
3881 se fizer um método implodido, o código fonte será:
3882 function implode_method ($array, $piece) {
3883 return array_reduce ($array, função ($carry, $item) uso ($piece) {
3884 devolver! $carregar? $item: ($carry $piece $item);
3885 });
3886 }
3887 $result = implode_method (["olá", "mundo", "PHP", "idioma"], "");
3888 resultado: "helloworldlinguagem PHP"
3889 Seção 14.6: Empurre um valor em uma matriz
3890 Existem duas maneiras de enviar um elemento para um array: array_push e $array [] =
3891 O array_push é usado assim:
3892 $array = [1,2,3];
3893 $newArraySize = array_push ($array, 5, 6); //O método retorna o novo tamanho da matriz
3894 print_r ($array); //Array é passado por referência, portanto o array original é
modificado para
3895 FF
3896 Notas PHP para Profissionais 88
3897 conter os novos elementos
3898 Este código irá imprimir:
3899 Matriz
3900 (
3901 [0] => 1
3902 [1] => 2
3903 [2] => 3
3904 [3] => 5
3905 [4] => 6
3906 )
3907 $array [] = é usado assim:
3908 $array = [1,2,3];
3909 $array [] = 5;
3910 $array [] = 6;
3911 print_r ($array);
3912 Este código irá imprimir:
3913 Matriz
3914 (
3915 [0] => 1
3916 [1] => 2
3917 [2] => 3
3918 [3] => 5
3919 [4] => 6
3920 )
3921 FF
3922 Notas PHP para Profissionais 89
3923 Capítulo 15: Manipulando uma Matriz
3924 Seção 15.1: Filtrando uma matriz
3925 Para filtrar os valores de uma matriz e obter uma nova matriz contendo todos os
valores que satisfazem o filtro
3926 condição, você pode usar a função array_filter
3927 Filtrando valores não vazios
3928 O caso mais simples de filtragem é remover todos os valores "vazios":
3929 $my_array = [1,0,2, null, 3, ', 4, [], 5,6,7,8];
3930 $non_empties = array_filter ($my_array); //$non_empties conterá [1,2,3,4,5,6,7,8];
3931 Filtrando por Retorno de Chamada
3932 Desta vez, definimos nossa própria regra de filtragem Suponha que queremos obter
apenas números pares:
3933 $my_array = [1,2,3,4,5,6,7,8];
3934 $even_numbers = array_filter ($my_array, function ($number) {
3935 return $number% 2 === 0;
3936 });
3937 A função array_filter recebe o array a ser filtrado como seu primeiro argumento e um
callback definindo o filtro
3938 predicado como seu segundo
3939 Versão = 5,6
3940 Filtrando por índice
3941 Um terceiro parâmetro pode ser fornecido para a função array_filter, que permite
ajustar quais valores são passados para
3942 o retorno de chamada Esse parâmetro pode ser definido como ARRAY_FILTER_USE_KEY ou
ARRAY_FILTER_USE_BOTH, que será
3943 resultará no retorno de chamada recebendo a chave em vez do valor para cada elemento
na matriz, ou tanto valor quanto chave como
3944 seus argumentos Por exemplo, se você quiser lidar com índices, há valores:
3945 $numbers = [16,3,5,8,1,4,6];
3946 $even_indexed_numbers = array_filter (números $, função ($index) {
3947 return $index% 2 === 0;
3948 }, ARRAY_FILTER_USE_KEY);
3949 Índices na matriz filtrada
3950 Note que array_filter preserva as chaves do array original Um erro comum seria
tentar usar o loop
3951 a matriz filtrada:
3952 <?php
3953 $my_array = [1,0,2, null, 3, ', 4, [], 5,6,7,8];
3954 $filtrado = array_filter ($my_array);
3955 error_reporting (E_ALL); //mostra todos os erros e avisos
3956 //procurando inocentemente o loop "for"
3957 para ($i = 0; $i <count ($filtrado); $i ++) {
3958 imprima $filtrado [$i];
3959 }
3960 FF
3961 Notas PHP para Profissionais 90
3962 /*
3963 Saída:
3964 1
3965 Aviso: indefinido deslocamento: 1
3966 2
3967 Aviso: indefinido deslocamento: 3
3968 3
3969 Aviso: indefinido deslocamento: 5
3970 4
3971 Aviso: Offset indefinido: 7
3972 */
3973 Isso acontece porque os valores que estavam nas posições 1 (era 0), 3 (nulo), 5
(string vazia '') e 7 (vazio)
3974 array []) foram removidos junto com suas chaves de índice correspondentes
3975 Se você precisa percorrer o resultado de um filtro em uma matriz indexada, você deve
primeiro chamar array_values no
3976 resultado de array_filter para criar uma nova matriz com os índices corretos:
3977 $my_array = [1,0,2, null, 3, ', 4, [], 5,6,7,8];
3978 $filtrado = array_filter ($my_array);
3979 $iterável = array_values ($filtrado);
3980 error_reporting (E_ALL); //mostra todos os erros e avisos
3981 para ($i = 0; $i <count ($iterável); $i ++) {
3982 print $iterável [$i];
3983 }
3984 //Sem avisos!
3985 Seção 15.2: Removendo elementos de uma matriz
3986 Para remover um elemento dentro de uma matriz, por exemplo, o elemento com o índice 1
3987 $fruit = array ("bananas", "maçãs", "pêssegos");
3988 não definido ($fruit [1]);
3989 Isso removerá as maçãs da lista, mas observe que o não definido não altera os
índices do restante
3990 elementos Então $fruit agora contém os índices 0 e 2.
3991 Para array associativo você pode remover assim:
3992 $fruit = array ('banana', 'one' => 'maçã', 'pêssego');
3993 print_r ($fruit);
3994 /*
3995 Matriz
3996 (
3997 [0] => banana
3998 [um] => maçã
3999 [1] => pêssegos
4000 )
4001 */
4002 unset ($fruit ['um']);
4003 Agora $fruta é
4004 FF
4005 Notas PHP para Profissionais 91
4006 print_r ($fruit);
4007 /*
4008 Matriz
4009 (
4010 [0] => banana
4011 [1] => pêssegos
4012 )
4013 */
4014 Observe que
4015 unset ($fruit);
4016 anula a variável e, assim, remove toda a matriz, o que significa que nenhum dos seus
elementos está mais acessível
4017 Removendo os elementos terminais
4018 array_shift () Desloca um elemento para fora do começo do array
4019 Exemplo:
4020 $fruit = array ("bananas", "maçãs", "pêssegos");
4021 array_shift ($fruit);
4022 print_r ($fruit);
4023 Saída:
4024 Matriz
4025 (
4026 [0] => maçãs
4027 [1] => pêssegos
4028 )
4029 array_pop () Pop o elemento fora do final da matriz
4030 Exemplo:
4031 $fruit = array ("bananas", "maçãs", "pêssegos");
4032 array_pop ($fruit);
4033 print_r ($fruit);
4034 Saída:
4035 Matriz
4036 (
4037 [0] => bananas
4038 [1] => maçãs
4039 )
4040 Seção 15.3: Classificando uma matriz
4041 Existem várias funções de classificação para matrizes no php:
4042 ordenar()
4043 Classifique uma matriz em ordem crescente por valor.
4044 FF
4045 Notas PHP para Profissionais 92
4046 $fruits = ['Zitrone', 'Orange', 'Banane', 'Apfel'];
4047 sort ($frutas);
4048 print_r ($frutas);
4049 resulta em
4050 Matriz
4051 (
4052 [0] => Apfel
4053 [1] => Banane
4054 [2] => laranja
4055 [3] => Zitrone
4056 )
4057 rsort ()
4058 Classifique uma matriz em ordem decrescente por valor
4059 $fruits = ['Zitrone', 'Orange', 'Banane', 'Apfel'];
4060 rsort ($frutos);
4061 print_r ($frutas);
4062 resulta em
4063 Matriz
4064 (
4065 [0] => Zitrone
4066 [1] => laranja
4067 [2] => Banane
4068 [3] => Apfel
4069 )
4070 um tipo()
4071 Classifique uma matriz em ordem crescente por valor e preserve os índices
4072 $fruits = [1 => 'limão', 2 => 'laranja', 3 => 'banana', 4 => 'maçã'];
4073 asort ($frutas);
4074 print_r ($frutas);
4075 resulta em
4076 Matriz
4077 (
4078 [4] => maçã
4079 [3] => banana
4080 [1] => limão
4081 [2] => laranja
4082 )
4083 arsort ()
4084 Classifique uma matriz em ordem decrescente por valor e preserve os índices
4085 $fruits = [1 => 'limão', 2 => 'laranja', 3 => 'banana', 4 => 'maçã'];
4086 arsort ($frutos);
4087 print_r ($frutas);
4088 resulta em
4089 FF
4090 Notas PHP para Profissionais 93
4091 Matriz
4092 (
4093 [2] => laranja
4094 [1] => limão
4095 [3] => banana
4096 [4] => maçã
4097 )
4098 ksort ()
4099 Ordenar uma matriz em ordem crescente por chave
4100 $fruits = ['d' => 'limão', 'a' => 'laranja', 'b' => 'banana', 'c' => 'maçã'];
4101 ksort ($frutos);
4102 print_r ($frutas);
4103 resulta em
4104 Matriz
4105 (
4106 [a] => laranja
4107 [b] => banana
4108 [c] => maçã
4109 [d] => limão
4110 )
4111 krsort ()
4112 Classifique uma matriz em ordem decrescente por chave
4113 $fruits = ['d' => 'limão', 'a' => 'laranja', 'b' => 'banana', 'c' => 'maçã'];
4114 krsort ($frutas);
4115 print_r ($frutas);
4116 resulta em
4117 Matriz
4118 (
4119 [d] => limão
4120 [c] => maçã
4121 [b] => banana
4122 [a] => laranja
4123 )
4124 natsort ()
4125 Classifique um array de uma forma que um ser humano faria (ordem natural)
4126 $files = ['File8.stack', 'file77.stack', 'file7.stack', 'file13.stack',
'File2.stack'];
4127 natsort ($arquivos);
4128 print_r ($files);
4129 resulta em
4130 Matriz
4131 (
4132 [4] => File2.stack
4133 [0] => Arquivo8.stack
4134 [2] => arquivo7.stack
4135 [3] => arquivo13.stack
4136 FF
4137 Notas PHP para Profissionais 94
4138 [1] => arquivo77.stack
4139 )
4140 natcasesort ()
4141 Ordenar um array de uma maneira que um ser humano faria (ordem natural), mas
intensivo de casos
4142 $files = ['File8.stack', 'file77.stack', 'file7.stack', 'file13.stack',
'File2.stack'];
4143 natcasesort ($arquivos);
4144 print_r ($files);
4145 resulta em
4146 Matriz
4147 (
4148 [4] => File2.stack
4149 [2] => arquivo7.stack
4150 [0] => Arquivo8.stack
4151 [3] => arquivo13.stack
4152 [1] => arquivo77.stack
4153 )
4154 shuffle ()
4155 Embaralha uma matriz (classificada aleatoriamente)
4156 $array = ['aa', 'bb', 'cc'];
4157 shuffle ($array);
4158 print_r ($array);
4159 Como está escrito na descrição é aleatório, então aqui apenas um exemplo no que pode
resultar
4160 Matriz
4161 (
4162 [0] => cc
4163 [1] => bb
4164 [2] => aa
4165 )
4166 usort ()
4167 Classifique uma matriz com uma função de comparação definida pelo usuário
4168 função compare ($a, $b)
4169 {
4170 if ($a == $b) {
4171 return 0;
4172 }
4173 retorno ($a <$b)? 1: 1;
4174 }
4175 $array = [3, 2, 5, 6, 1];
4176 usort ($array, 'compare');
4177 print_r ($array);
4178 resulta em
4179 Matriz
4180 (
4181 [0] => 1
4182 FF
4183 Notas PHP para Profissionais 95
4184 [1] => 2
4185 [2] => 3
4186 [3] => 5
4187 [4] => 6
4188 )
4189 uasort ()
4190 Classifique uma matriz com uma função de comparação definida pelo usuário e preserve
as chaves
4191 função compare ($a, $b)
4192 {
4193 if ($a == $b) {
4194 return 0;
4195 }
4196 retorno ($a <$b)? 1: 1;
4197 }
4198 $array = ['a' => 1, 'b' => 3, 'c' => 5, 'd' => 3, 'e' => 5];
4199 uasort ($array, 'compare');
4200 print_r ($array);
4201 resulta em
4202 Matriz
4203 (
4204 [e] => 5
4205 [b] => 3
4206 [a] => 1
4207 [d] => 3
4208 [c] => 5
4209 )
4210 uksort ()
4211 Classifique um array por chaves com uma função de comparação definida pelo usuário
4212 função compare ($a, $b)
4213 {
4214 if ($a == $b) {
4215 return 0;
4216 }
4217 retorno ($a <$b)? 1: 1;
4218 }
4219 $array = ['ee' => 1, 'g' => 3, '4' => 5, 'k' => 3, 'oo' => 5];
4220 uksort ($array, 'compare');
4221 print_r ($array);
4222 resulta em
4223 Matriz
4224 (
4225 [ee] => 1
4226 [g] => 3
4227 [k] => 3
4228 [oo] => 5
4229 [4] => 5
4230 )
4231 FF
4232 Notas PHP para Profissionais 96
4233 Seção 15.4: Whitelist apenas algumas chaves de matriz
4234 Quando você deseja permitir apenas determinadas chaves em seus arrays, especialmente
quando o array vem de parâmetros de solicitação,
4235 você pode usar array_intersect_key junto com array_flip
4236 $parameters = ['foo' => 'barra', 'barra' => 'baz', 'boo' => 'bam'];
4237 $allowedKeys = ['foo', 'bar'];
4238 $filteredParameters = array_intersect_key ($parameters, array_flip ($allowedKeys));
4239 //$filteredParameters contém ['foo' => 'bar', 'bar' => 'baz]
4240 Se a variável de parâmetros não contiver nenhuma chave permitida, a variável
filteredParameters consistirá em uma
4241 matriz vazia
4242 Desde o PHP 5.6 você pode usar array_filter para esta tarefa também, passando o flag
ARRAY_FILTER_USE_KEY como o terceiro
4243 parâmetro:
4244 $parameters = ['foo' => 1, 'olá' => 'mundo'];
4245 $allowedKeys = ['foo', 'bar'];
4246 $filteredParameters = array_filter (
4247 $parameters
4248 função ($key) use ($allowedKeys) {
4249 return in_array (tecla $, $allowedKeys);
4250 }
4251 ARRAY_FILTER_USE_KEY
4252 );
4253 Usar array_filter fornece a flexibilidade adicional de realizar um teste arbitrário
em relação à chave, por exemplo, $allowedKeys
4254 pode conter padrões de regex em vez de strings simples Também declara mais
explicitamente a intenção do código do que
4255 array_intersect_key () combinado com array_flip ()
4256 Seção 15.5: Adicionando elemento ao início do array
4257 Às vezes você deseja adicionar um elemento ao início de um array sem modificar
nenhum dos
4258 elementos (ordem) dentro da matriz Sempre que este for o caso, você pode usar
array_unshift ().
4259 array_unshift () preenche os elementos passados para a frente da matriz Note que a
lista de elementos é
4260 prefixado como um todo, para que os elementos prefixados permaneçam na mesma ordem
Todas as chaves do array numérico
4261 será modificado para começar a contar a partir de zero, enquanto as teclas literais
não serão tocadas
4262 Extraído da documentação do PHP para array_unshift ()
4263 Se você gostaria de conseguir isso, tudo que você precisa fazer é o seguinte:
4264 $myArray = array (1, 2, 3);
4265 array_unshift ($myArray, 4);
4266 Isso agora adicionará 4 como o primeiro elemento em sua matriz Você pode verificar
isso por:
4267 print_r ($myArray);
4268 Isso retorna uma matriz na seguinte ordem: 4, 1, 2, 3.
4269 FF
4270 Notas PHP para Profissionais 97
4271 Como array_unshift força a matriz a redefinir os pares de valorchave como o novo
elemento, deixe as entradas a seguir
4272 as chaves n + 1 é mais inteligente para criar uma nova matriz e anexar a matriz
existente à matriz recémcriada
4273 Exemplo:
4274 $myArray = array ('maçãs', 'bananas', 'pêras');
4275 $myElement = array ('laranjas');
4276 $joinedArray = $myElement;
4277 foreach ($myArray como $i) {
4278 $joinedArray [] = $i;
4279 }
4280 Saída ($joinedArray):
4281 Matriz ([0] => laranjas [1] => maçãs [2] => bananas [3] => peras)
4282 Eaxmple /Demo
4283 Seção 15.6: Valores do Exchange com chaves
4284 A função array_flip trocará todas as chaves com seus elementos
4285 $colors = array (
4286 'one' => 'vermelho',
4287 'dois' => 'azul'
4288 'três' => 'amarelo',
4289 );
4290 array_flip ($colors); //resultará
4291 array (
4292 'vermelho' => 'um',
4293 'azul' => 'dois',
4294 'amarelo' => 'três'
4295 )
4296 Seção 15.7: Mesclar dois arrays em um array
4297 $a1 = array ("vermelho", "verde");
4298 $a2 = array ("azul", "amarelo");
4299 print_r (array_merge ($a1, $a2));
4300 /*
4301 Matriz ([0] => vermelho [1] => verde [2] => azul [3] => amarelo)
4302 */
4303 Matriz associativa:
4304 $a1 = array ("a" => "vermelho", "b" => "verde");
4305 $a2 = array ("c" => "azul", "b" => "amarelo");
4306 print_r (array_merge ($a1, $a2));
4307 /*
4308 Matriz ([a] => vermelho [b] => amarelo [c] => azul)
4309 */
4310 1 Mescla os elementos de um ou mais arrays juntos para que os valores de um sejam
anexados ao final de
4311 FF
4312 Notas PHP para Profissionais 98
4313 o anterior Ele retorna a matriz resultante.
4314 2 Se as matrizes de entrada tiverem as mesmas chaves de cadeia, o valor mais recente
dessa chave substituirá o anterior
4315 Se, no entanto, as matrizes contiverem chaves numéricas, o valor mais recente não
substituirá o valor original, mas será
4316 acrescentado
4317 3 Os valores na matriz de entrada com chaves numéricas serão renumerados com chaves
de incremento começando em zero em
4318 o array de resultados.
4319 FF
4320 Notas PHP para Profissionais 99
4321 Capítulo 16: Processando vários arrays
4322 Juntos
4323 Seção 16.1: Interseção da matriz
4324 A função array_intersect retornará uma matriz de valores que existem em todas as
matrizes que foram passadas para essa função
4325 $array_one = ['one', 'two', 'three'];
4326 $array_two = ['dois', 'tres', 'quatro'];
4327 $array_three = ['dois', 'três'];
4328 $intersect = array_intersect ($array_one, $array_two, $array_three);
4329 //$intersect contém ['two', 'three']
4330 As chaves de matriz são preservadas Índices das matrizes originais não são.
4331 Somente array_intersect verifica os valores dos arrays A função
array_intersect_assoc retornará a interseção de
4332 matrizes com chaves
4333 $array_one = [1 => 'um', 2 => 'dois', 3 => 'tres'];
4334 $array_two = [1 => 'um', 2 => 'dois', 3 => 'dois', 4 => 'tres'];
4335 $array_three = [1 => 'um', 2 => 'dois'];
4336 $intersect = array_intersect_assoc ($array_one, $array_two, $array_three);
4337 //$intersect contém [1 => 'one', 2 => 'two']
4338 função array_intersect_key apenas verificar a intersecção de chaves Ele retornará
chaves existem em todas as matrizes.
4339 $array_one = [1 => 'um', 2 => 'dois', 3 => 'tres'];
4340 $array_two = [1 => 'um', 2 => 'dois', 3 => 'quatro'];
4341 $array_three = [1 => 'um', 3 => 'cinco'];
4342 $intersect = array_intersect_key ($array_one, $array_two, $array_three);
4343 //$intersect contém [1 => 'one', 3 => 'three']
4344 Seção 16.2: Mesclar ou concatenar matrizes
4345 $fruit1 = ['maçãs', 'pêras'];
4346 $fruit2 = ['bananas', 'laranjas'];
4347 $all_of_fruits = array_merge ($fruit1, $fruit2);
4348 //agora o valor de $all_of_fruits é [0 => 'apples', 1 => 'pears', 2 => 'bananas', 3
=> 'laranjas']
4349 Note que array_merge irá alterar índices numéricos, mas sobrescrever índices de
string
4350 $fruit1 = ['one' => 'apples', 'two' => 'pêras'];
4351 $fruit2 = ['one' => 'bananas', 'dois' => 'laranjas'];
4352 $all_of_fruits = array_merge ($fruit1, $fruit2);
4353 //agora o valor de $all_of_fruits é ['one' => 'bananas', 'two' => 'laranjas']
4354 array_merge sobrescreve os valores da primeira matriz com os valores da segunda
matriz, se não puder renumerar a
4355 índice
4356 Você pode usar o operador + para mesclar duas matrizes de forma que os valores da
primeira matriz nunca sejam sobrescritos, mas
4357 FF
4358 Notas PHP para Profissionais 100
4359 ele não renumera os índices numéricos, então você perde valores de arrays que
possuem um índice que também é usado no primeiro
4360 array
4361 $fruit1 = ['one' => 'apples', 'two' => 'pêras'];
4362 $fruit2 = ['one' => 'bananas', 'dois' => 'laranjas'];
4363 $all_of_fruits = $fruit1 + $fruit2;
4364 //agora o valor de $all_of_fruits é ['one' => 'apples', 'two' => 'pears']
4365 $fruit1 = ['maçãs', 'pêras'];
4366 $fruit2 = ['bananas', 'laranjas'];
4367 $all_of_fruits = $fruit1 + $fruit2;
4368 //agora o valor de $all_of_fruits é [0 => 'apples', 1 => 'pears']
4369 Seção 16.3: Mudando um array multidimensional para associativo
4370 matriz
4371 Se você tem um array multidimensional como este:
4372 [
4373 ['foo', 'bar'],
4374 ['fizz', 'buzz'],
4375 ]
4376 E você quer mudálo para um array associativo como este:
4377 [
4378 'foo' => 'bar',
4379 'fizz' => 'buzz',
4380 ]
4381 Você pode usar este código:
4382 $multidimensionalArray = [
4383 ['foo', 'bar'],
4384 ['fizz', 'buzz'],
4385 ];
4386 $associativeArrayKeys = array_column ($multidimensionalArray, 0);
4387 $associativeArrayValues = array_column ($multidimensionalArray, 1);
4388 $associativeArray = array_combine ($associativeArrayKeys, $associativeArrayValues);
4389 Ou, você pode pular a configuração $associativeArrayKeys e $associativeArrayValues e
usar este simples liner:
4390 $associativeArray = array_combine (array_column ($multidimensionalArray, 0),
4391 array_column ($multidimensionalArray, 1));
4392 Seção 16.4: Combinando dois arrays (chaves de um, valores
4393 de outro)
4394 O exemplo a seguir mostra como mesclar dois arrays em um array associativo, onde os
valores de chave serão os
4395 itens da primeira matriz, e os valores serão da segunda:
4396 $array_one = ['key1', 'key2', 'key3'];
4397 $array_two = ['valor1', 'valor2', 'valor3'];
4398 FF
4399 Notas PHP para Profissionais 101
4400 $array_three = array_combine ($array_one, $array_two);
4401 var_export ($array_three);
4402 /*
4403 array (
4404 'key1' => 'valor1',
4405 'key2' => 'valor2',
4406 'key3' => 'value3',
4407 )
4408 */
4409 FF
4410 Notas PHP para Profissionais 102
4411 Capítulo 17: Classe de Data e Hora
4412 Seção 17.1: Criar versão imutável do DateTime de
4413 Mutável anterior ao PHP 5.6
4414 Para criar \ DateTimeImmutable no PHP 5.6+ use:
4415 \ DateTimeImmutable :: createFromMutable ($concrete);
4416 Antes PHP 5.6 você pode usar:
4417 \ DateTimeImmutable :: createFromFormat (\ DateTime :: ISO8601, formato $mutable> (\
DateTime :: ISO8601),
4418 $mutable> getTimezone ());
4419 Seção 17.2: Adicionar ou subtrair intervalos de data
4420 Podemos usar a classe DateInterval para adicionar ou subtrair algum intervalo em um
objeto DateTime
4421 Veja o exemplo abaixo, onde estamos adicionando um intervalo de 7 dias e imprimindo
uma mensagem na tela:
4422 $now = new DateTime (); //argumento vazio retorna a data atual
4423 $interval = new DateInterval ('P7D'); //este objeto representa um intervalo de 7 dias
4424 $lastDay = $now> add (intervalo $); //isso retornará um objeto DateTime
4425 $formatedLastDay = $lastDay> format ('Ymd'); //este método formata o objeto DateTime
e retorna um
4426 Corda
4427 echo "Samara diz: Sete Dias Você ficará feliz em $formatedLastDay.";
4428 Isso será exibido (em 1º de agosto de 2016):
4429 Samara diz: Sete Dias Você será feliz em 20160808.
4430 Podemos usar o método sub de maneira semelhante para subtrair datas
4431 $now> sub ($interval);
4432 eco "Samara diz: Sete Dias Você foi feliz por último em $formatedLastDay.";
4433 Isso será exibido (em 1º de agosto de 2016):
4434 Samara diz: Sete Dias Você ficou feliz em 20160725.
4435 Seção 17.3: getTimestamp
4436 getTimeStemp é uma representação unix de um objeto datetime
4437 $date = new DateTime ();
4438 echo $date> getTimestamp ();
4439 Isto irá colocar uma indicação inteira dos segundos que se passaram desde 00:00:00
UTC, quintafeira, 1 de janeiro de 1970.
4440 FF
4441 Notas PHP para Profissionais 103
4442 Seção 17.4: setDate
4443 setDate define a data em um objeto DateTime
4444 $date = new DateTime ();
4445 $date> setDate (2016, 7, 25);
4446 este exemplo define a data como o vigésimo quinto de julho de 2015, produzirá o
seguinte resultado:
4447 20160725 17: 52: 15.819442
4448 Seção 17.5: Criar o DateTime no formato personalizado
4449 O PHP é capaz de analisar vários formatos de data Se você quiser analisar um formato
fora do padrão ou se quiser
4450 código para indicar explicitamente o formato a ser usado, então você pode usar o
método DateTime :: createFromFormat estático:
4451 Estilo orientado a objetos
4452 $format = "Y, m, d";
4453 $time = "2009,2,26";
4454 $date = DateTime :: createFromFormat ($format, $time);
4455 Estilo processual
4456 $format = "Y, m, d";
4457 $time = "2009,2,26";
4458 $date = date_create_from_format ($format, $time);
4459 Seção 17.6: Imprimindo DateTimes
4460 O PHP 4+ fornece um método, formato que converte um objeto DateTime em uma string
com o formato desejado De acordo com
4461 Manual PHP, esta é a função orientada a objetos:
4462 public string DateTime :: format (formato string $)
4463 A função date () recebe um parâmetro um formato, que é uma string
4464 Formato
4465 O formato é uma string e usa caracteres únicos para definir o formato:
4466 Y: representação de quatro dígitos do ano (por exemplo: 2016)
4467 y: representação de dois dígitos do ano (por exemplo: 16)
4468 m: mês, como um número (01 a 12)
4469 M: mês, como três letras (jan, fev, mar, etc)
4470 j: dia do mês, sem zeros à esquerda (1 a 31)
4471 D: dia da semana, como três letras (Seg, Ter, Qua, etc)
4472 h: hora (formato de 12 horas) (01 a 12)
4473 H: hora (formato de 24 horas) (00 a 23)
4474 A: ou AM ou PM
4475 i: minuto, com zeros à esquerda (00 a 59)
4476 s: segundo, com zeros à esquerda (00 a 59)
4477 A lista completa pode ser encontrada aqui
4478 FF
4479 Notas PHP para Profissionais 104
4480 Uso
4481 Esses caracteres podem ser usados em várias combinações para exibir horários em
praticamente qualquer formato Aqui estão alguns
4482 exemplos:
4483 $date = new DateTime ('20000526T13: 30: 20'); /* Sextafeira, 26 de maio de 2000 às
13h30min20s */
4484 $date> format ("H: i");
4485 /* Retorna 13:30 */
4486 $date> format ("H i s");
4487 /* Retorna 13 30 20 */
4488 $date> format ("h: i: s A");
4489 /* Retorna 01:30:20 */
4490 $date> format ("j /m /Y");
4491 /* Retorna 26/05/2000 */
4492 $date> format ("D, M j 'y h: i A");
4493 /* Retorna Sex, 26 de maio 13: 30h */
4494 Procedural
4495 O formato processual é semelhante:
4496 Orientado a Objeto
4497 $date> format (formato $)
4498 Equivalente processual
4499 date_format ($date, $format)
4500 FF
4501 Notas PHP para Profissionais 105
4502 Capítulo 18: Trabalhando com Datas e Tempo
4503 Seção 18.1: Obtendo a diferença entre duas datas /horas
4504 A maneira mais viável é usar a classe DateTime
4505 Um exemplo:
4506 <?php
4507 //Cria um objeto de data e hora, que tem o valor de ~ dois anos atrás
4508 $twoYearsAgo = new DateTime ("20140118 20:05:56");
4509 //Cria um objeto de data e hora, que tem o valor de ~ now
4510 $now = new DateTime ("20160721 02:55:07");
4511 //Calcular o diff
4512 $diff = $now> diff ($twoYearsAgo);
4513 //$diff> y contém a diferença em anos entre as duas datas
4514 $yearsDiff = $diff> y;
4515 //$diff> m contém a diferença em minutos entre as duas datas
4516 $monthsDiff = $diff> m;
4517 //$diff> d contém a diferença em dias entre as duas datas
4518 $daysDiff = $diff> d;
4519 //$diff> h contém a diferença de horas entre as duas datas
4520 $hoursDiff = $diff> h;
4521 //$diff> i contém a diferença em minutos entre as duas datas
4522 $minsDiff = $diff> i;
4523 //$diff> s contém a diferença em segundos entre as duas datas
4524 $secondsDiff = $diff> s;
4525 //Total de dias Diff, ou seja, o número de dias entre as duas datas
4526 $totalDaysDiff = $diff> dias;
4527 //Despeja a diferença completamente apenas para obter alguns detalhes;)
4528 var_dump ($diff);
4529 Além disso, comparar duas datas é muito mais fácil, basta usar os operadores de
comparação, como:
4530 <?php
4531 //Cria um objeto de data e hora, que tem o valor de ~ dois anos atrás
4532 $twoYearsAgo = new DateTime ("20140118 20:05:56");
4533 //Cria um objeto de data e hora, que tem o valor de ~ now
4534 $now = new DateTime ("20160721 02:55:07");
4535 var_dump ($now> $twoYearsAgo); //imprime bool (true)
4536 var_dump ($twoYearsAgo> $agora); //imprime bool (false)
4537 var_dump ($twoYearsAgo <= $twoYearsAgo); //imprime bool (true)
4538 var_dump ($agora == $agora); //imprime bool (true)
4539 Seção 18.2: Converter uma data em outro formato
4540 O básico
4541 A maneira simplista de converter um formato de data em outro é usar strtotime () com
date () strtotime () será
4542 Converta a data em um carimbo de data /hora Unix Esse carimbo de data /hora Unix
pode então ser passado para data () para convertêlo para o
4543 novo formato
4544 $timestamp = strtotime ('20080701T22: 35: 17.02');
4545 FF
4546 Notas PHP para Profissionais 106
4547 $new_date_format = date ('Ymd H: i: s', $timestamp);
4548 Ou como um oneliner:
4549 $new_date_format = date ('Ymd H: i: s', strtotime ('20080701T22: 35: 17.02'));
4550 Tenha em mente que strtotime () requer que a data esteja em um formato válido Não
fornecer um formato válido resultará
4551 em strtotime () retornando false, o que fará com que sua data seja 19691231
4552 Usando DateTime ()
4553 A partir do PHP 5.2, o PHP oferecia a classe DateTime () que nos oferece ferramentas
mais poderosas para trabalhar com datas (e
4554 Tempo) Podemos reescrever o código acima usando DateTime () da seguinte forma:
4555 $date = new DateTime ('20080701T22: 35: 17.02');
4556 $new_date_format = formato $date> ('Ymd H: i: s');
4557 Trabalhando com timestamps Unix
4558 date () recebe um timestamp do Unix como segundo parâmetro e retorna uma data
formatada para você:
4559 $new_date_format = date ('Ymd H: i: s', '1234567890');
4560 DateTime () trabalha com timestamps Unix adicionando um @ antes do timestamp:
4561 $date = new DateTime ('@ 1234567890');
4562 $new_date_format = formato $date> ('Ymd H: i: s');
4563 Se o timestamp que você tem é em milissegundos (pode terminar em 000 e /ou o
timestamp tem treze caracteres)
4564 você precisará convertêlo para segundos antes que possa convertêlo em outro formato
Existem duas maneiras de fazer isso:
4565 Apare os últimos três dígitos usando substr ()
4566 Cortar os últimos três dígitos pode ser obtido de várias maneiras, mas usar substr
() é o mais fácil:
4567 $timestamp = substr ('1234567899000', 3);
4568 Divida o substr por 1000
4569 Você também pode converter o registro de data e hora em segundos dividindo por 1000
Como o registro de data e hora é muito grande para 32 bits
4570 sistemas para fazer matemática em você precisará usar a biblioteca BCMath para fazer
as contas como strings:
4571 $timestamp = bcdiv ('1234567899000', '1000');
4572 Para obter um carimbo de data /hora Unix, você pode usar strtotime (), que retorna
um carimbo de data /hora Unix:
4573 $timestamp = strtotime ('19730418');
4574 Com DateTime () você pode usar DateTime :: getTimestamp ()
4575 $date = new DateTime ('20080701T22: 35: 17.02');
4576 $timestamp = $date> getTimestamp ();
4577 Se você estiver executando o PHP 5.2, você pode usar a opção de formatação U:
4578 FF
4579 Notas PHP para Profissionais 107
4580 $date = new DateTime ('20080701T22: 35: 17.02');
4581 $timestamp = $date> format ('U');
4582 Trabalhando com formatos de data não padrão e ambíguos
4583 Infelizmente, nem todas as datas com as quais um desenvolvedor precisa trabalhar
estão em um formato padrão Felizmente PHP 5.3
4584 nos forneceu uma solução para isso DateTime :: createFromFormat () nos permite dizer
ao PHP o formato de uma string de data
4585 está em modo que possa ser analisado com sucesso em um objeto DateTime para
manipulação adicional
4586 $date = DateTime :: createFromFormat ('FdY h: i A', '18 de abril de 1973, 9:48 AM');
4587 $new_date_format = formato $date> ('Ymd H: i: s');
4588 No PHP 5.4 nós ganhamos a habilidade de fazer o acesso dos membros da classe na
instanciação foi adicionado o que nos permite transformar
4589 nosso código DateTime () em um oneliner:
4590 $new_date_format = (new DateTime ('20080701T22: 35: 17.02')) > formato ('Ymd H: i:
s');
4591 Infelizmente isso não funciona com DateTime :: createFromFormat () ainda
4592 Seção 18.3: Analisar descrições de datas em inglês em uma data
4593 formato
4594 Usando a função strtotime () combinada com date () você pode analisar diferentes
descrições de texto em inglês para datas:
4595 //Obtém a data atual
4596 data de eco ("m /d /Y", strtotime ("now")), "\ n"; //imprime a data atual
4597 data de eco ("m /d /Y", strtotime ("10 de setembro de 2000")), "\ n"; //imprime 10
de setembro de 2000 em m /d /Y
4598 formato
4599 data de eco ("m /d /Y", strtotime (" 1 dia")), "\ n"; //imprime a data de ontem
4600 data de eco ("m /d /Y", strtotime ("+ 1 semana")), "\ n"; //imprime o resultado da
data atual + uma semana
4601 data de eco ("m /d /Y", strtotime ("+ 1 semana 2 dias 4 horas 2 segundos")), "\ n";
//o mesmo que o último
4602 exemplo, mas com dias extras, horas e segundos adicionados a ele
4603 data de eco ("m /d /Y", strtotime ("próxima quintafeira")), "\ n"; //imprime a data
da próxima quintafeira
4604 data de eco ("m /d /Y", strtotime ("segundafeira passada")), "\ n"; //imprime a data
da segundafeira passada
4605 data de eco ("m /d /Y", strtotime ("Primeiro dia do próximo mês")), "\ n"; //imprime
data do primeiro dia da próxima
4606 mês
4607 data de eco ("m /d /Y", strtotime ("Último dia do próximo mês")), "\ n"; //imprime
data do último dia do próximo
4608 mês
4609 data de eco ("m /d /Y", strtotime ("Primeiro dia do último mês")), "\ n"; //imprime
data do primeiro dia do último
4610 mês
4611 data de eco ("m /d /Y", strtotime ("Último dia do último mês")), "\ n"; //imprime a
data do último dia do último
4612 mês
4613 Seção 18.4: Usando constantes predefinidas para o formato de data
4614 Podemos usar Constantes Predefinidas para formato de data em data () em vez das
strings de formato de data convencionais desde
4615 PHP 5.1.0
4616 Constantes de formato de data predefinidas disponíveis
4617 DATE_ATOM Atom (20160722T14: 50: 01 + 00: 00)
4618 DATE_COOKIE Cookies HTTP (Sextafeira, 22Jul16 14:50:01 UTC)
4619 DATE_RSS RSS (Sex, 22 de julho de 2016 14:50:01 +0000)
4620 FF
4621 Notas PHP para Profissionais 108
4622 DATE_W3C World Wide Web Consortium (20160722T14: 50: 01 + 00: 00)
4623 DATE_ISO8601 ISO8601 (20160722T14: 50: 01 + 0000)
4624 DATE_RFC822 RFC 822 (sex, 22 jul 16 14:50:01 +0000)
4625 DATE_RFC850 RFC 850 (sextafeira, 22 de julho de 16 14:50:01 UTC)
4626 DATE_RFC1036 RFC 1036 (sex, 22 jul 16 14:50:01 +0000)
4627 DATE_RFC1123 RFC 1123 (Sex, 22 de julho de 2016 14:50:01 +0000)
4628 DATE_RFC2822 RFC 2822 (Sex, 22 de julho de 2016 14:50:01 +0000)
4629 DATE_RFC3339 O mesmo que DATE_ATOM (20160722T14: 50: 01 + 00: 00)
4630 Exemplos de uso
4631 data de eco (DATE_RFC822);
4632 Isto irá produzir: Fri, 22 Jul 16 14:50:01 +0000
4633 data de eco (DATE_ATOM, mktime (0,0,0,8,15,1947));
4634 Isso resultará em: 19470815T00: 00: 00 + 05: 30
4635 FF
4636 Notas PHP para Profissionais 109
4637 Capítulo 19: Estruturas de Controle
4638 Seção 19.1: se mais
4639 A instrução if no exemplo acima permite executar um fragmento de código, quando a
condição é atendida Quando você
4640 quer executar um fragmento de código, quando a condição não é atendida você estende
o if com um else
4641 if ($a> $b) {
4642 echo "a é maior que b";
4643 } outro {
4644 echo "a não é maior que b";
4645 }
4646 Manual PHP Estruturas de Controle Else
4647 O operador ternário como sintaxe abreviada para ifelse
4648 O operador ternário avalia algo com base em uma condição sendo verdadeira ou não É
um operador de comparação e
4649 freqüentemente usado para expressar uma condição ifelse simples em um formato mais
curto Permite testar rapidamente uma condição e muitas vezes
4650 substitui uma instrução if de várias linhas, tornando seu código mais compacto
4651 Este é o exemplo acima usando uma expressão ternária e valores variáveis: $a = 1; $b
= 2;
4652 eco ($a> $b)? "a é maior que b": "a não é maior que b";
4653 Saídas: a não é maior que b
4654 Seção 19.2: Sintaxe alternativa para estruturas de controle
4655 O PHP fornece uma sintaxe alternativa para algumas estruturas de controle: if,
while, for, foreach e switch
4656 Quando comparado com a sintaxe normal, a diferença é que a chave de abertura é
substituída por dois pontos (:) e
4657 a chave de fechamento é substituída por endif ;, endwhile; endfor ;, endforeach; ou
endswitch; respectivamente Para indivíduo
4658 exemplos, consulte o tópico sobre sintaxe alternativa para estruturas de controle
4659 if ($a == 42):
4660 eco "A resposta para a vida, o universo e tudo é 42.";
4661 fim se;
4662 Múltiplas instruções elseif usando sintaxe curta:
4663 if ($a == 5):
4664 eco "a igual a 5";
4665 elseif ($a == 6):
4666 echo "a é igual a 6";
4667 outro:
4668 eco "a não é nem 5 nem 6";
4669 fim se;
4670 Manual do PHP Estruturas de Controle Sintaxe Alternativa
4671 Seção 19.3: enquanto
4672 while loop itera através de um bloco de código, desde que uma condição especificada
seja verdadeira.
4673 FF
4674 Notas PHP para Profissionais 110
4675 $i = 1;
4676 while ($i <10) {
4677 echo $i;
4678 $i ++;
4679 }
4680 Saída:
4681 123456789
4682 Para informações detalhadas, consulte o tópico Loops
4683 Seção 19.4: doenquanto
4684 O loop dowhile primeiro executa um bloco de código uma vez, em cada caso, depois
percorre esse bloco de código, desde que
4685 uma condição especificada é verdadeira
4686 $i = 0;
4687 Faz {
4688 $i ++;
4689 echo $i;
4690 } while ($i <10);
4691 Saída: 12345678910
4692 Para informações detalhadas, consulte o tópico Loops
4693 Seção 19.5: goto
4694 O operador goto permite pular para outra seção no programa Está disponível desde o
PHP 5.3.
4695 A instrução goto é um goto seguido pelo rótulo de destino desejado: goto MyLabel ;
4696 O alvo do salto é especificado por um rótulo seguido por dois pontos: MyLabel :
4697 Este exemplo irá imprimir Hello World !:
4698 <?php
4699 goto MyLabel;
4700 echo 'Este texto será pulado, devido ao salto.';
4701 MyLabel:
4702 eco 'Olá, mundo!';
4703 ?>
4704 Seção 19.6: declarar
4705 declare é usado para definir uma diretiva de execução para um bloco de código
4706 As seguintes diretivas são reconhecidas:
4707 carrapatos
4708 codificação
4709 strict_types
4710 Por exemplo, defina carrapatos para 1:
4711 FF
4712 Notas PHP para Profissionais 111
4713 declarar (carrapatos = 1);
4714 Para ativar o modo de tipo estrito, a declaração declare é usada com a declaração
strict_types:
4715 declarar (strict_types = 1);
4716 Seção 19.7: incluir e exigir
4717 exigir
4718 require é semelhante a incluir, exceto que produzirá um erro fatal de nível
E_COMPILE_ERROR na falha Quando o
4719 requer falhar, ele irá interromper o script Quando a inclusão falhar, ela não
interromperá o script e somente emitirá E_WARNING.
4720 requer 'file.php';
4721 Manual PHP Estruturas de Controle Exigir
4722 incluir
4723 A instrução include inclui e avalia um arquivo
4724 ./variables.php
4725 $a = 'Olá mundo!';
4726 /main.php`
4727 inclua 'variables.php';
4728 echo $a;
4729 //Output: "Olá mundo!"
4730 Tenha cuidado com essa abordagem, pois ela é considerada um cheiro de código, porque
o arquivo incluído está alterando a quantidade e
4731 conteúdo das variáveis definidas no escopo dado
4732 Você também pode incluir arquivo, que retorna um valor Isso é extremamente útil para
manipular matrizes de configuração:
4733 configuration.php
4734 <?php
4735 Retorna [
4736 'dbname' => 'meu db',
4737 'user' => 'admin',
4738 'pass' => 'senha',
4739 ];
4740 main.php
4741 <? php
4742 FF
4743 Notas PHP para Profissionais 112
4744 $config = incluir 'configuration.php';
4745 Essa abordagem impedirá que o arquivo incluído polua seu escopo atual com variáveis
alteradas ou adicionadas
4746 Manual PHP Estruturas de Controle Incluir
4747 include & require também pode ser usado para atribuir valores a uma variável quando
retornou algo por arquivo
4748 Exemplo:
4749 arquivo include1.php:
4750 <?php
4751 $a = "Isso deve ser retornado";
4752 devolve $a;
4753 ?>
4754 arquivo index.php:
4755 $value = incluir 'include1.php';
4756 //Aqui, $value = "Isso deve ser retornado"
4757 Seção 19.8: retorno
4758 A declaração de retorno retorna o controle de programa para a função de chamada
4759 Quando o retorno é chamado de dentro de uma função, a execução da função atual
terminará
4760 função returnEndsFunctions ()
4761 {
4762 echo 'Isto é executado';
4763 Retorna;
4764 echo 'Isto não é executado.';
4765 }
4766 Quando você executa returnEndsFunctions (); você obterá a saída Isso é executado;
4767 Quando o retorno é chamado de dentro de uma função com e argumento, a execução da
função atual terminará e
4768 o valor do argumento será retornado para a função de chamada
4769 Seção 19.9: para
4770 Os loops for normalmente são usados quando você tem um pedaço de código que deseja
repetir um determinado número de vezes
4771 para ($i = 1; $i <10; $i ++) {
4772 echo $i;
4773 }
4774 Saídas:
4775 123456789
4776 Para informações detalhadas, consulte o tópico Loops.
4777 FF
4778 Notas PHP para Profissionais 113
4779 Seção 19.10: foreach
4780 foreach é uma construção, que permite iterar facilmente sobre matrizes e objetos
4781 $array = [1, 2, 3];
4782 foreach ($array como $value) {
4783 echo $value;
4784 }
4785 Saídas:
4786 123
4787 .
4788 Para usar o loop foreach com um objeto, ele deve implementar a interface Iterator
4789 Quando você itera sobre matrizes associativas:
4790 $array = ['cor' => 'vermelho'];
4791 foreach ($array como $key => $value) {
4792 echo $chave ':' valor $;
4793 }
4794 Saídas:
4795 cor vermelha
4796 Para informações detalhadas, consulte o tópico Loops
4797 Seção 19.11: se elseif else
4798 elseif
4799 elseif combina se e mais A declaração if é estendida para executar uma declaração
diferente no caso de o original se
4800 expressão não é cumprida Mas, a expressão alternativa é executada apenas quando a
expressão condicional elseif é
4801 conheceu
4802 O código a seguir exibe "a é maior que b", "a é igual a b" ou "a é menor que b":
4803 if ($a> $b) {
4804 echo "a é maior que b";
4805 } elseif ($a == $b) {
4806 echo "a é igual a b";
4807 } outro {
4808 eco "a é menor que b";
4809 }
4810 Várias declarações elseif
4811 Você pode usar várias instruções elseif dentro da mesma instrução if:
4812 if ($a == 1) {
4813 eco "a é um";
4814 } elseif ($a == 2) {
4815 eco "a é dois";
4816 FF
4817 Notas PHP para Profissionais 114
4818 } elseif ($a == 3) {
4819 eco "a é três";
4820 } outro {
4821 eco "a não é um, nem dois nem três";
4822 }
4823 Seção 19.12: se
4824 A construção if permite a execução condicional de fragmentos de código
4825 if ($a> $b) {
4826 echo "a é maior que b";
4827 }
4828 Manual PHP Estruturas de Controle Se
4829 Seção 19.13: alternar
4830 A estrutura do switch executa a mesma função que uma série de instruções if, mas
pode fazer o trabalho em menos linhas de
4831 código O valor a ser testado, conforme definido na instrução switch, é comparado por
igualdade com os valores em cada um dos
4832 as declarações case até encontrar uma correspondência e o código nesse bloco é
executado Se nenhuma declaração de caso correspondente for
4833 encontrado, o código no bloco padrão é executado, se existir
4834 Cada bloco de código em um caso ou declaração padrão deve terminar com a instrução
break Isso interrompe a execução
4835 da estrutura do switch e continua a execução do código imediatamente depois Se a
instrução break for omitida,
4836 o código da próxima instrução do caso é executado, mesmo que não haja
correspondência Isso pode causar execução inesperada de código se
4837 a instrução break é esquecida, mas também pode ser útil quando várias instruções de
caso precisam compartilhar o mesmo
4838 código
4839 switch ($color) {
4840 caso "vermelho":
4841 eco "a cor é vermelha";
4842 pausa;
4843 caso "verde":
4844 caso "azul":
4845 eco "a cor é verde ou azul";
4846 pausa;
4847 caso "amarelo":
4848 eco "a cor é amarela";
4849 //note falta de pausa, o próximo bloco também será executado
4850 caso "preto":
4851 eco "a cor é preta";
4852 pausa;
4853 padrão:
4854 eco "a cor é outra coisa";
4855 pausa;
4856 }
4857 Além de testar valores fixos, a construção também pode ser coagida para testar
instruções dinâmicas fornecendo
4858 valor booleano para a instrução switch e qualquer expressão para a instrução case
Tenha em mente a primeira correspondência
4859 value é usado, então o código a seguir produzirá "mais de 100":
4860 $i = 1048;
4861 switch (true) {
4862 caso ($i> 0):
4863 eco "mais de 0";
4864 pausa;
4865 FF
4866 Notas PHP para Profissionais 115
4867 caso ($i> 100):
4868 eco "mais de 100";
4869 pausa;
4870 caso ($i> 1000):
4871 eco "mais de 1000";
4872 pausa;
4873 }
4874 Para possíveis problemas com digitação solta ao usar a construção de opção, consulte
Switch Surprises
4875 FF
4876 Notas PHP para Profissionais 116
4877 Capítulo 20: Loops
4878 Loops são um aspecto fundamental da programação Eles permitem que os programadores
criem código que se repete para alguns
4879 determinado número de repetições ou iterações O número de iterações pode ser
explícito (6 iterações, por exemplo) ou
4880 continue até que alguma condição seja satisfeita ('até que o inferno congele')
4881 Este tópico abrange os diferentes tipos de loops, suas declarações de controle
associadas e seus possíveis aplicativos em
4882 PHP
4883 Seção 20.1: continuar
4884 A palavrachave continue interrompe a iteração atual de um loop, mas não finaliza o
loop
4885 Assim como a instrução break, a instrução continue está situada dentro do corpo do
loop Quando executado, o
4886 A instrução continue faz com que a execução salte imediatamente para o loop
condicional
4887 No exemplo a seguir, o loop imprime uma mensagem com base nos valores de uma matriz,
mas ignora um valor especificado
4888 $list = ['apple', 'banana', 'cereja'];
4889 foreach ($list como $value) {
4890 if ($value == 'banana') {
4891 continuar;
4892 }
4893 echo "Adoro comer {$value} torta" PHP_EOL;
4894 }
4895 A saída esperada é:
4896 Eu amo comer torta de maçã
4897 Eu amo comer torta de cereja
4898 A instrução continue também pode ser usada para continuar imediatamente a execução
para um nível externo de um loop
4899 especificando o número de níveis de loop para pular Por exemplo, considere dados como
4900 Custo da cor da fruta
4901 Maçã vermelha 1
4902 Banana Amarela 7
4903 Cereja vermelha 2
4904 Uva Verde 4
4905 A fim de fazer apenas tortas de frutas que custam menos de 5
4906 $data = [
4907 ["Fruit" => "Apple", "Color" => "Red", "Cost" => 1],
4908 ["Fruit" => "Banana", "Color" => "Yellow", "Cost" => 7],
4909 ["Fruit" => "Cherry", "Color" => "Red", "Cost" => 2],
4910 ["Fruit" => "Grape", "Color" => "Green", "Cost" => 4]
4911 ];
4912 foreach ($data as $fruit) {
4913 foreach ($fruit como $key => $value) {
4914 if ($key == "Custo" && $value> = 5) {
4915 FF
4916 Notas PHP para Profissionais 117
4917 continue 2;
4918 }
4919 /* fazer uma torta */
4920 }
4921 }
4922 Quando a instrução continue 2 é executada, a execução imediatamente retorna para
$data, enquanto $fruit continua
4923 o loop externo e ignorando todos os outros códigos (incluindo o condicional no loop
interno
4924 Seção 20.2: quebra
4925 A palavrachave break interrompe imediatamente o loop atual
4926 Semelhante à instrução continue, uma quebra interrompe a execução de um loop
Diferentemente de uma instrução continue, no entanto, break
4927 causa o término imediato do loop e não executa a instrução condicional novamente
4928 $i = 5;
4929 while (true) {
4930 eco 120 /$i.PHP_EOL;
4931 $i = 1;
4932 if ($i == 0) {
4933 pausa;
4934 }
4935 }
4936 Este código irá produzir
4937 24
4938 30
4939 40
4940 60
4941 120
4942 mas não executará o caso em que $i é 0, o que resultaria em um erro fatal devido à
divisão por 0
4943 A instrução break também pode ser usada para romper vários níveis de loops Esse
comportamento é muito útil quando
4944 executando loops aninhados Por exemplo, para copiar uma matriz de strings em uma
string de saída, removendo quaisquer # símbolos,
4945 até que a string de saída tenha exatamente 160 caracteres
4946 $output = "";
4947 $inputs = array (
4948 "#soblessed #throwbackthursday",
4949 "feliz terçafeira",
4950 "#Sem filtro",
4951 /* mais entradas */
4952 );
4953 foreach ($inputs como $input) {
4954 para ($i = 0; $i <strlen (entrada $); $i + = 1) {
4955 if ($input [$i] == '#') continuar;
4956 $output = $input [$i];
4957 if (strlen ($output) == 160) quebra 2;
4958 }
4959 $output = '';
4960 }
4961 O comando break 2 encerra imediatamente a execução dos loops interno e externo.
4962 FF
4963 Notas PHP para Profissionais 118
4964 Seção 20.3: foreach
4965 A instrução foreach é usada para percorrer as matrizes
4966 Para cada iteração, o valor do elemento da matriz atual é atribuído à variável
$value e o ponteiro da matriz é
4967 movido por um e na próxima iteração o próximo elemento será processado
4968 O exemplo a seguir exibe os itens na matriz atribuída
4969 $list = ['apple', 'banana', 'cereja'];
4970 foreach ($list como $value) {
4971 echo "Adoro comer {$value}.";
4972 }
4973 A saída esperada é:
4974 Eu amo comer maçã Eu amo comer banana Eu amo comer cereja.
4975 Você também pode acessar a chave /índice de um valor usando foreach:
4976 foreach ($list como $key => $value) {
4977 echo $chave ":" valor $ "";
4978 }
4979 //Saídas 0: maçã 1: banana 2: cereja
4980 Por padrão, $value é uma cópia do valor em $list, portanto as alterações feitas
dentro do loop não serão refletidas na lista $
4981 depois
4982 foreach ($list como $value) {
4983 $value = $value "pie";
4984 }
4985 echo $list [0]; //Saídas "apple"
4986 Para modificar o array dentro do loop foreach, use o operador & para atribuir $value
por referência É importante
4987 desmarque a variável depois para que reutilizar $value em outro lugar não
sobrescreva o array
4988 foreach ($list as & $value) {//Ou foreach ($list como $key => & $value) {
4989 $value = $value "pie";
4990 }
4991 unset (valor $);
4992 echo $list [0]; //Saídas "torta de maçã"
4993 Você também pode modificar os itens da matriz dentro do loop foreach referenciando a
chave da matriz do item atual
4994 foreach ($list como $key => $value) {
4995 $list [$key] = $valor "pie";
4996 }
4997 echo $list [0]; //Saídas "torta de maçã"
4998 Seção 20.4: fazer .enquanto
4999 FF
5000 Notas PHP para Profissionais 119
5001 A declaração do .while irá executar um bloco de código pelo menos uma vez então irá
repetir o loop por tanto tempo
5002 como uma condição é verdadeira
5003 O exemplo a seguir incrementará o valor de $i pelo menos uma vez e continuará
incrementando a variável $i
5004 contanto que tenha um valor menor que 25;
5005 $i = 0;
5006 Faz {
5007 $i ++;
5008 } while ($i <25);
5009 echo 'O valor final de i é:', $i;
5010 A saída esperada é:
5011 O valor final de i é: 25
5012 Seção 20.5: para
5013 A instrução for é usada quando você sabe quantas vezes deseja executar uma instrução
ou um bloco
5014 de declarações
5015 O inicializador é usado para definir o valor inicial para o contador do número de
iterações de loop Uma variável pode ser
5016 aqui declarado para este fim e é tradicional nomeálo $i
5017 O exemplo a seguir é repetido 10 vezes e exibe números de 0 a 9
5018 para ($i = 0; $i <= 9; $i ++) {
5019 echo $i, ',';
5020 }
5021 # Exemplo 2
5022 para ($i = 0;; $i ++) {
5023 if ($i> 9) {
5024 pausa;
5025 }
5026 echo $i, ',';
5027 }
5028 # Exemplo 3
5029 $i = 0;
5030 para (; ; ) {
5031 if ($i> 9) {
5032 pausa;
5033 }
5034 echo $i, ',';
5035 $i ++;
5036 }
5037 # Exemplo 4
5038 para ($i = 0, $j = 0; $i <= 9; $j + = $i, imprima $i ',', $i ++);
5039 A saída esperada é:
5040 0,1,2,3,4,5,6,7,8,9,
5041 FF
5042 Notas PHP para Profissionais 120
5043 Seção 20.6: enquanto
5044 A instrução while executará um bloco de código se e enquanto uma expressão de teste
for verdadeira
5045 Se a expressão de teste for verdadeira, o bloco de código será executado Após o
código ter executado a expressão de teste
5046 será novamente avaliado e o loop continuará até que a expressão de teste seja
considerada falsa
5047 O exemplo a seguir itera até a soma atingir 100 antes de terminar
5048 $i = true;
5049 $sum = 0;
5050 while ($i) {
5051 if ($sum === 100) {
5052 $i = false;
5053 } outro {
5054 $sum + = 10;
5055 }
5056 }
5057 echo 'A soma é:', $sum;
5058 A saída esperada é:
5059 A soma é: 100
5060 FF
5061 Notas PHP para Profissionais 121
5062 Capítulo 21: Funções
5063 Seção 21.1: Listas de argumentos de tamanho variável
5064 Versão = 5,6
5065 O PHP 5.6 introduziu listas de argumentos de comprimento variável (também conhecido
como varargs, argumentos variadic), usando o .token antes
5066 o nome do argumento para indicar que o parâmetro é variádico, ou seja, é um array
que inclui todos os parâmetros fornecidos
5067 daquele em diante
5068 function variadic_func ($nonVariadic, .$variadic) {
5069 echo json_encode ($variadic);
5070 }
5071 variadic_func (1, 2, 3, 4); //imprime [2,3,4]
5072 Nomes de tipos podem ser adicionados na frente do ...:
5073 função foo (Bar .$bars) {}
5074 O operador & reference pode ser adicionado antes do ..., mas depois do nome do tipo
(se houver) Considere este exemplo:
5075 classe Foo {}
5076 função a (Foo & .$foos) {
5077 $i = 0;
5078 foreach ($a as & $foo) {//observe o &
5079 $foo = $i ++;
5080 }
5081 }
5082 $a = novo Foo;
5083 $c = novo Foo;
5084 $b = & $c;
5085 um ($a, $b);
5086 var_dump ($a, $b, $c);
5087 Saída:
5088 int (0)
5089 int (1)
5090 int (1)
5091 Por outro lado, um array (ou Traversable) de argumentos pode ser descompactado para
ser passado para uma função na forma
5092 de uma lista de argumentos:
5093 var_dump (.hash_algos ());
5094 Saída:
5095 string (3) "md2"
5096 string (3) "md4"
5097 string (3) "md5"
5098 .
5099 Compare com este snippet sem usar ...:
5100 FF
5101 Notas PHP para Profissionais 122
5102 var_dump (hash_algos ());
5103 Saída:
5104 matriz (46) {
5105 [0] =>
5106 string (3) "md2"
5107 [1] =>
5108 string (3) "md4"
5109 .
5110 }
5111 Portanto, as funções de redirecionamento para funções variadicas agora podem ser
feitas facilmente, por exemplo:
5112 função pública formatQuery ($query, .$args) {
5113 return sprintf ($query, .array_map ([$mysqli, "real_escape_string"], $args));
5114 }
5115 Além de matrizes, Traversables, como Iterator (especialmente muitas de suas
subclasses de SPL) também podem ser usados
5116 Por exemplo:
5117 $iterator = new LimitIterator (novo ArrayIterator ([0, 1, 2, 3, 4, 5, 6]), 2, 3);
5118 echo bin2hex (pack ("c *", .$isso)); //Output: 020304
5119 Se o iterador repetir infinitamente, por exemplo:
5120 $iterator = new InfiniteIterator (novo ArrayIterator ([0, 1, 2, 3, 4]));
5121 var_dump (.$iterador);
5122 Diferentes versões do PHP se comportam de maneira diferente:
5123 Do PHP 7.0.0 até o PHP 7.1.0 (beta 1):
5124 Uma falha de segmentação ocorrerá
5125 O processo PHP irá sair com o código 139
5126 No PHP 5.6:
5127 Um erro fatal de exaustão de memória ("Permitido tamanho da memória de% d bytes
esgotado") será mostrado
5128 O processo do PHP irá sair com o código 255
5129 Nota: O HHVM (v3.10 v3.12) não suporta a descompactação de Traversables Uma
mensagem de aviso "Apenas
5130 recipientes podem ser descompactados "será mostrado nesta tentativa
5131 Seção 21.2: Parâmetros opcionais
5132 Funções podem ter parâmetros opcionais, por exemplo:
5133 função olá ($nome, $estilo = 'Formal')
5134 {
5135 switch ($style) {
5136 case 'Formal':
5137 print "Bom Dia $nome";
5138 pausa;
5139 case 'Informal':
5140 print "Hi $name";
5141 FF
5142 Notas PHP para Profissionais 123
5143 pausa;
5144 caso 'australiano':
5145 print "G'day $name";
5146 pausa;
5147 padrão:
5148 print "Olá $nome";
5149 pausa;
5150 }
5151 }
5152 ola ('Alice');
5153 //Bom Dia Alice
5154 ola ('Alice', 'australiano');
5155 //G'day Alice
5156 Seção 21.3: Passando argumentos por referência
5157 Os argumentos da função podem ser passados "por referência", permitindo que a função
modifique a variável usada fora da
5158 função:
5159 função pluralize (& $word)
5160 {
5161 if (substr ($word, 1) == 'y') {
5162 $word = substr ($word, 0, 1) 's';
5163 } outro {
5164 $word = 's';
5165 }
5166 }
5167 $palavra = 'Bannana';
5168 pluralizar ($word);
5169 imprima $palavra;
5170 //Bannanas
5171 Argumentos de objetos são sempre passados por referência:
5172 function addOneDay ($date)
5173 {
5174 $date> modify ('+ 1 dia');
5175 }
5176 $date = new DateTime ('20140228');
5177 addOneDay ($date);
5178 imprima $date> format ('Ymd');
5179 //20140301
5180 Para evitar a passagem implícita de um objeto por referência, você deve clonar o
objeto
5181 A passagem por referência também pode ser usada como uma maneira alternativa de
retornar parâmetros Por exemplo, o
5182 função socket_getpeername:
5183 bool socket_getpeername (recurso $socket, string & $endereço [, int & $port])
5184 Na verdade, esse método tem como objetivo retornar o endereço e a porta do peer, mas
como há dois valores a serem retornados,
5185 opta por usar parâmetros de referência Pode ser chamado assim:
5186 FF
5187 Notas PHP para Profissionais 124
5188 if (! socket_getpeername ($socket, $endereço, $port)) {
5189 throw new RuntimeException (socket_last_error ());
5190 }
5191 echo "Peer: $address: $port \ n";
5192 As variáveis $address e $port não precisam ser definidas antes Elas vão:
5193 1 ser definido como nulo primeiro,
5194 2 então passou para a função com o valor nulo predefinido
5195 3 então modificado na função
5196 4 termina definido como o endereço e porta no contexto de chamada
5197 Seção 21.4: Uso Básico da Função
5198 Uma função básica é definida e executada assim:
5199 função olá ($nome)
5200 {
5201 print "Olá $nome";
5202 }
5203 ola ("Alice");
5204 Seção 21.5: Escopo da Função
5205 Variáveis dentro de funções estão dentro de um escopo local como este
5206 $number = 5
5207 função foo () {
5208 $number = 10
5209 return $number
5210 }
5211 foo (); //Imprime 10 porque o texto definido dentro da função é uma variável local
5212 FF
5213 Notas PHP para Profissionais 125
5214 Capítulo 22: Programação Funcional
5215 A programação funcional do PHP depende de funções Funções em PHP fornecem código
reutilizável organizado para executar um
5216 conjunto de ações As funções simplificam o processo de codificação, evitam a lógica
redundante e facilitam o acompanhamento do código este
5217 tópico descreve a declaração e utilização de funções, argumentos, parâmetros,
declarações de retorno e escopo em
5218 PHP
5219 Seção 22.1: Encerramentos
5220 Um encerramento é uma função anônima que não pode acessar o escopo externo
5221 Ao definir uma função anônima, você está criando um "namespace" para essa função
Atualmente apenas
5222 tem acesso a esse namespace
5223 $externalVariable = "Olá";
5224 $secondExternalVariable = "Foo";
5225 $myFunction = function () {
5226 var_dump ($externalVariable, $secondExternalVariable); //retorna dois avisos de
erro, uma vez que o
5227 variáveis não são definidas
5228 }
5229 Não tem acesso a nenhuma variável externa Para conceder essa permissão para esse
namespace acessar
5230 variáveis, você precisa introduzilo através de fechamentos (use ())
5231 $myFunction = function () use ($externalVariable, $secondExternalVariable) {
5232 var_dump ($externalVariable, $secondExternalVariable); //Olá, Foo
5233 }
5234 Isso é fortemente atribuído ao estreito escopo de variáveis do PHP Se uma variável
não é definida dentro do escopo, ou não é trazida
5235 com global então não existe
5236 Observe também:
5237 Herdar variáveis do escopo pai não é o mesmo que usar variáveis globais Variáveis
globais existem
5238 no escopo global, que é o mesmo, não importa qual função esteja sendo executada
5239 O escopo pai de um fechamento é a função na qual o fechamento foi declarado (não
necessariamente
5240 função foi chamado de)
5241 Extraído da Documentação PHP para Funções Anônimas
5242 No PHP, os encerramentos usam uma abordagem de vinculação antecipada Isso significa
que as variáveis passadas para o namespace do fechamento
5243 using use keyword terá os mesmos valores quando o fechamento foi definido
5244 Para alterar esse comportamento, você deve passar a variável por referência
5245 $rate = 0,05;
5246 //Exporta a variável para o escopo do fechamento
5247 $calculateTax = function ($value) use ($rate) {
5248 FF
5249 Notas PHP para Profissionais 126
5250 return $value * $rate;
5251 };
5252 $rate = .1;
5253 print $calculateTax (100); //5
5254 $rate = 0,05;
5255 //Exporta a variável para o escopo do fechamento
5256 $calculateTax = use função ($valor) (& $rate) {//observe a taxa & before $
5257 return $value * $rate;
5258 };
5259 $rate = .1;
5260 print $calculateTax (100); //10
5261 Argumentos padrão não são implicitamente necessários ao definir funções anônimas com
/sem closures
5262 $message = 'Estou gritando com você';
5263 $yell = function () use ($message) {
5264 strtoupper de eco (mensagem $);
5265 };
5266 $yell (); //retorna: IM YELLING AT YOU
5267 Seção 22.2: Atribuição a variáveis
5268 Funções anônimas podem ser atribuídas a variáveis para uso como parâmetros onde um
retorno de chamada é esperado:
5269 $uppercase = function ($data) {
5270 return strtoupper ($data);
5271 };
5272 $mixedCase = ["Olá", "Mundo"];
5273 $uppercased = array_map ($maiúscula, $mixedCase);
5274 print_r ($uppercased);
5275 Essas variáveis também podem ser usadas como chamadas de função independentes:
5276 echo $uppercase ("Hello world!"); //OLÁ MUNDO!
5277 Seção 22.3: Objetos como uma função
5278 class SomeClass {
5279 função pública __invoke ($param1, $param2) {
5280 //coloque seu código aqui
5281 }
5282 }
5283 $instance = new SomeClass ();
5284 $instance ('First', 'Second'); //chama o método __invoke ()
5285 Um objeto com um método __invoke pode ser usado exatamente como qualquer outra função
5286 O método __invoke terá acesso a todas as propriedades do objeto e poderá chamar
qualquer método.
5287 FF
5288 Notas PHP para Profissionais 127
5289 Seção 22.4: Usando variáveis externas
5290 A construção de uso é usada para importar variáveis para o escopo da função anônima:
5291 $divisor = 2332;
5292 $myfunction = function ($number) use ($divisor) {
5293 return $number /$divisor;
5294 };
5295 echo $myfunction (81620); //Saídas 35
5296 Variáveis também podem ser importadas por referência:
5297 $collection = [];
5298 $additem = function ($item) use (& $collection) {
5299 $collection [] = $item;
5300 };
5301 $additem (1);
5302 $additem (2);
5303 //$collection é agora [1,2]
5304 Seção 22.5: Função Anônima
5305 Uma função anônima é apenas uma função que não tem nome
5306 //Função anônima
5307 function () {
5308 return "Olá, mundo!";
5309 };
5310 No PHP, uma função anônima é tratada como uma expressão e, por essa razão, deve ser
terminada com uma
5311 ponto e vírgula;
5312 Uma função anônima deve ser atribuída a uma variável
5313 //Função anônima atribuída a uma variável
5314 $sayHello = function ($name) {
5315 return "Olá $name!";
5316 };
5317 print $sayHello ('John'); //Olá john
5318 Ou deveria ser passado como parâmetro de outra função
5319 $users = [
5320 ['name' => 'Alice', 'idade' => 20],
5321 ['name' => 'Bobby', 'idade' => 22],
5322 ['name' => 'Carol', 'idade' => 17]
5323 ];
5324 //Mapear função aplicando função anônima
5325 $userName = array_map (function ($user) {
5326 return $user ['nome'];
5327 }, $usuários);
5328 FF
5329 Notas PHP para Profissionais 128
5330 print_r ($usersName); //['Alice', 'Bobby', 'Carol']
5331 Ou até mesmo foi retornado de outra função
5332 Funções anônimas autoexecutáveis:
5333 //Para PHP 7.x
5334 (function () {
5335 eco "Olá mundo!";
5336 }) ();
5337 //Para PHP 5.x
5338 call_user_func (function () {
5339 eco "Olá mundo!";
5340 });
5341 Passando um argumento para funções anônimas autoexecutáveis:
5342 //Para PHP 7.x
5343 (function ($name) {
5344 echo "Olá $nome!";
5345 })('John');
5346 //Para PHP 5.x
5347 call_user_func (function ($name) {
5348 echo "Olá $nome!";
5349 }, 'John');
5350 Seção 22.6: Funções puras
5351 Uma função pura é uma função que, dada a mesma entrada, sempre retornará a mesma
saída e será efeito colateral
5352 livre
5353 //esta é uma função pura
5354 função add ($a, $b) {
5355 devolve $a + $b;
5356 }
5357 Alguns efeitos colaterais estão alterando o sistema de arquivos, interagindo com
bancos de dados, imprimindo na tela
5358 //Esta é uma função impura
5359 função add ($a, $b) {
5360 echo "Adicionando ...";
5361 devolve $a + $b;
5362 }
5363 Seção 22.7: Métodos funcionais comuns em PHP
5364 Mapeamento
5365 Aplicando uma função para todos os elementos de uma matriz:
5366 array_map ('strtoupper', $array);
5367 Esteja ciente de que esse é o único método da lista em que o retorno de chamada vem
primeiro.
5368 FF
5369 Notas PHP para Profissionais 129
5370 Reduzindo (ou dobrando)
5371 Reduzindo uma matriz para um valor único:
5372 $sum = array_reduce (números $, função ($carry, $number) {
5373 return $carry + $number;
5374 });
5375 Filtrando
5376 Retorna apenas os itens da matriz para os quais o retorno retorna verdadeiro:
5377 $onlyEven = array_filter (números $, função ($number) {
5378 return ($number% 2) === 0;
5379 });
5380 Seção 22.8: Usando funções internas como retornos de chamada
5381 Em funções que utilizam callable como argumento, você também pode colocar uma string
com a função interna do PHP É comum
5382 use trim como parâmetro array_map para remover espaços em branco à esquerda e à
direita de todas as strings da matriz
5383 $arr = ['one', 'two', 'three'];
5384 var_dump (array_map ('trim', $arr));
5385 //array (3) {
5386 //[0] =>
5387 //string (3) "um"
5388 //[1] =>
5389 //string (3) "dois"
5390 //[2] =>
5391 //string (5) "três"
5392 //}
5393 Seção 22.9: Escopo
5394 No PHP, uma função anônima tem seu próprio escopo como qualquer outra função PHP
5395 Em JavaScript, uma função anônima pode acessar uma variável no escopo externo Mas no
PHP, isso não é permitido.
5396 $name = 'John';
5397 //Função anônima tentando acessar o escopo externo
5398 $sayHello = function () {
5399 return "Olá $name!";
5400 }
5401 print $sayHello ('John'); //Olá !
5402 //Com avisos ativos, há também uma variável indefinida $name notice
5403 Seção 22.10: passando uma função de retorno de chamada como um parâmetro
5404 Existem várias funções do PHP que aceitam funções de retorno de chamada definidas
pelo usuário como um parâmetro, como:
5405 call_user_func (), usort () e array_map ()
5406 Dependendo de onde a função de retorno de chamada definida pelo usuário foi
definida, há maneiras diferentes de passálas:
5407 Estilo processual:
5408 FF
5409 Notas PHP para Profissionais 130
5410 quadrado da função ($number)
5411 {
5412 return $number * $number;
5413 }
5414 $initial_array = [1, 2, 3, 4, 5];
5415 $final_array = array_map ('square', $initial_array);
5416 var_dump ($final_array); //imprime a nova matriz com 1, 4, 9, 16, 25
5417 Estilo orientado a objetos:
5418 classe SquareHolder
5419 {
5420 quadrado da função ($number)
5421 {
5422 return $number * $number;
5423 }
5424 }
5425 $squaredHolder = novo SquareHolder ();
5426 $initial_array = [1, 2, 3, 4, 5];
5427 $final_array = array_map ([$squaredHolder, 'square'], $initial_array);
5428 var_dump ($final_array); //imprime a nova matriz com 1, 4, 9, 16, 25
5429 Estilo orientado a objetos usando um método estático:
5430 classe StaticSquareHolder
5431 {
5432 quadrado de função estática pública ($number)
5433 {
5434 return $number * $number;
5435 }
5436 }
5437 $initial_array = [1, 2, 3, 4, 5];
5438 $final_array = array_map (['StaticSquareHolder', 'square'], $initial_array);
5439 //ou:
5440 $final_array = array_map ('StaticSquareHolder :: square', $initial_array); //para
PHP> = 5.2.3
5441 var_dump ($final_array); //imprime a nova matriz com 1, 4, 9, 16, 25
5442 FF
5443 Notas PHP para Profissionais 131
5444 Capítulo 23: Sintaxe Alternativa para Controle
5445 Estruturas
5446 Seção 23.1: Instrução alternativa if /else
5447 <?php
5448 if (condição $):
5449 faça alguma coisa();
5450 elseif ($another_condition):
5451 do_something_else ();
5452 outro:
5453 do_something_different ();
5454 fim se;
5455 ?>
5456 <?phpif ($condição):?>
5457 <p> Faça algo em HTML </p>
5458 <?phpelseif ($another_condition):?>
5459 <p> Faça outra coisa em HTML </p>
5460 <?phpelse:?>
5461 <p> Faça algo diferente em HTML </p>
5462 <?phpendif; ?>
5463 Seção 23.2: Alternativa para declaração
5464 <?php
5465 para ($i = 0; $i <10; $i ++):
5466 do_something ($i);
5467 endfor;
5468 ?>
5469 <?phppara ($i = 0; $i <10; $i ++):?>
5470 <p> Faça algo em HTML com <?phpecho $i; ?> </p>
5471 <?phpendfor; ?>
5472 Seção 23.3: Alternativa enquanto declaração
5473 <?php
5474 while ($condition):
5475 faça alguma coisa();
5476 ao final;
5477 ?>
5478 <?phpwhile ($condition):?>
5479 <p> Faça algo em HTML </p>
5480 <?phpendwhile; ?>
5481 Seção 23.4: Instrução alternativa para cada
5482 <? php
5483 FF
5484 Notas PHP para Profissionais 132
5485 foreach ($collection como $item):
5486 do_something ($item);
5487 endforeach;
5488 ?>
5489 <?phpforeach ($collection as $item):?>
5490 <p> Faça algo em HTML com <?phpecho $item; ?> </p>
5491 <?phpendforeach; ?>
5492 Seção 23.5: Instrução alternativa de troca
5493 <?php
5494 switch (condição $):
5495 case $value:
5496 faça alguma coisa();
5497 pausa;
5498 padrão:
5499 do_something_else ();
5500 pausa;
5501 endswitch;
5502 ?>
5503 <?phpswitch ($condition):?>
5504 <?phpcase $value: /* com espaços em branco antes que seus casos causem um erro */?>
5505 <p> Faça algo em HTML </p>
5506 <?phpbreak; ?>
5507 <?phpdefault:?>
5508 <p> Faça outra coisa em HTML </p>
5509 <?phpbreak; ?>
5510 <?phpendswitch; ?>
5511 FF
5512 Notas PHP para Profissionais 133
5513 Capítulo 24: Formatação de String
5514 Seção 24.1: Interpolação de string
5515 Você também pode usar a interpolação para interpolar (inserir) uma variável dentro
de uma string Interpolação funciona em duplo citado
5516 strings e a sintaxe heredoc apenas
5517 $name = 'Joel';
5518 //$name será substituído por `Joel`
5519 echo "<p> Olá $name, é bom ver você </p>";
5520 #
5521 #> "<p> Olá Joel, prazer em vêlo </p>"
5522 //Single Quotes: gera $name como o texto bruto (sem interpretálo)
5523 echo 'Olá $nome, bom te ver.'; # Cuidado com esta notação
5524 #> "Olá $name, bom ver você."
5525 O formato de sintaxe complexo (encaracolado) fornece outra opção que exige que você
envolva sua variável dentro
5526 chaves {} Isso pode ser útil ao incorporar variáveis dentro do conteúdo textual e
ajudar a evitar
5527 possível ambigüidade entre conteúdo textual e variáveis
5528 $name = 'Joel';
5529 //Exemplo usando a sintaxe da chave para a variável $name
5530 echo "<p> Precisamos de mais {$name} s para nos ajudar! </p>";
5531 #> "<p> Precisamos de mais Joels para nos ajudar! </p>"
5532 //Esta linha irá lançar um erro (como `$names` não está definido)
5533 echo "<p> Precisamos de mais $nomes para nos ajudar! </p>";
5534 #> "Aviso: variável indefinida: nomes"
5535 A sintaxe {} interpola apenas as variáveis que começam com $em uma string A sintaxe
{} não avalia arbitrariamente
5536 Expressões PHP
5537 //Exemplo de empate para interpolar uma expressão PHP
5538 eco "1 + 2 = {1 + 2}";
5539 #> "1 + 2 = {1 + 2}"
5540 //Exemplo usando uma constante
5541 define ("HELLO_WORLD", "Hello World !!");
5542 echo "Minha constante é {HELLO_WORLD}";
5543 #> "Minha constante é {HELLO_WORLD}"
5544 //Exemplo usando uma função
5545 function say_hello () {
5546 return "Olá!";
5547 };
5548 echo "Eu digo: {say_hello ()}";
5549 #> "Eu digo: {say_hello ()}"
5550 No entanto, a sintaxe {} avalia qualquer acesso de matriz, acesso a propriedades e
chamadas de função /método em variáveis,
5551 elementos ou propriedades da matriz:
5552 //Exemplo de acesso a um valor de um array acesso multidimensional é permitido
5553 $companions = [0 => ['name' => 'Amy Pond'], 1 => ['nome' => 'Dave Aleatório']];
5554 echo "O melhor companheiro é: {$companions [0] ['name']}";
5555 FF
5556 Notas PHP para Profissionais 134
5557 #> "O melhor companheiro é: Amy Pond"
5558 //Exemplo de chamar um método em um objeto instanciado
5559 class Person {
5560 function say_hello () {
5561 return "Olá!";
5562 }
5563 }
5564 $max = new Person ();
5565 echo "Max diz: {$max> say_hello ()}";
5566 #> "Max diz: Olá!"
5567 //Exemplo de invocação de um Closure a lista de parâmetros permite expressões
personalizadas
5568 $greet = function ($num) {
5569 return "A $num greetings!";
5570 };
5571 echo "De todos nós: {$greet (10 ** 3)}";
5572 #> "De todos nós: 1000 saudações!"
5573 Observe que o sinal $dollar pode aparecer após a chave de abertura {como os exemplos
acima, ou, como em Perl ou
5574 Shell Script, pode aparecer antes dele:
5575 $name = 'Joel';
5576 //Exemplo usando a sintaxe de chave com o cifrão antes da chave de abertura
5577 echo "<p> Precisamos de mais ${name} s para nos ajudar! </p>";
5578 #> "<p> Precisamos de mais Joels para nos ajudar! </p>"
5579 A sintaxe Complex (curly) não é chamada como tal porque é complexa, mas sim porque
permite
5580 o uso de 'expressões complexas' Leia mais sobre a sintaxe Complex (curly)
5581 Seção 24.2: Extraindo /substituindo substrings
5582 Caracteres únicos podem ser extraídos usando a sintaxe de matriz (chave quadrada),
bem como a sintaxe de chave Estes dois
5583 as sintaxes só retornarão um único caractere da string Se mais de um caractere for
necessário, uma função será
5584 necessário, ou seja, substr
5585 Strings, como tudo no PHP, são indexados em 0
5586 $foo = 'Olá mundo';
5587 $foo [6]; //retorna 'w'
5588 $foo {6}; //também retorna 'w'
5589 substr ($foo, 6, 1); //também retorna 'w'
5590 substr ($foo, 6, 2); //retorna 'wo'
5591 Seqüências de caracteres também podem ser alteradas um caractere por vez usando a
mesma chave de colchete e sintaxe de chave Substituindo
5592 mais de um caractere requer uma função, ie substr_replace
5593 $foo = 'Olá mundo';
5594 $foo [6] = 'W'; //resulta em $foo = 'Hello World'
5595 $foo {6} = 'W'; //também resulta em $foo = 'Hello World'
5596 FF
5597 Notas PHP para Profissionais 135
5598 substr_replace ($foo, 'W', 6, 1); //também resulta em $foo = 'Hello World'
5599 substr_replace ($foo, 'Whi', 6, 2); //resulta em 'Hello Whirled'
5600 //observe que a string de substituição não precisa ter o mesmo comprimento que a
substring substituída
5601 FF
5602 Notas PHP para Profissionais 136
5603 Capítulo 25: Análise de String
5604 Seção 25.1: Divisão de uma string por separadores
5605 explode e strstr são métodos mais simples para obter substrings por separadores
5606 Uma string contendo várias partes do texto separadas por um caractere comum pode ser
dividida em partes com o caractere
5607 função de explosão
5608 $fruits = "maçã, pêra, grapefruit, cereja";
5609 print_r (explode (",", $frutos)); //['apple', 'pear', 'grapefruit', 'cherry']
5610 O método também suporta um parâmetro limite que pode ser usado da seguinte forma:
5611 $frutas = maçã, pêra, grapefruit, cereja;
5612 Se o parâmetro limite for zero, isso é tratado como 1
5613 print_r (explode (',', $fruits, 0)); //['maçã, pêra, grapefruit, cereja']
5614 Se o limite for definido e positivo, a matriz retornada conterá um máximo de
elementos de limite com o último elemento
5615 contendo o resto da string
5616 print_r (explode (',', $fruits, 2)); //['maçã', 'pêra, grapefruit, cereja']
5617 Se o parâmetro limite for negativo, todos os componentes, exceto o último limite,
serão retornados
5618 print_r (explode (',', $fruits, 1)); //['apple', 'pear', 'grapefruit']
5619 explode pode ser combinado com a lista para analisar uma string em variáveis em uma
linha:
5620 $email = "user@example.com";
5621 list ($name, $domain) = explode ("@", $email);
5622 No entanto, certifiquese de que o resultado de explode contenha elementos
suficientes ou que um aviso de índice indefinido seja
5623 desencadeada
5624 strstr tiras de distância ou só retorna a substring antes da primeira ocorrência da
agulha dada
5625 $string = "1: 23: 456";
5626 echo json_encode (explode (":", $string)); //["1", "23", "456"]
5627 var_dump (strstr ($string, ":")); //string (7) ": 23: 456"
5628 var_dump (strstr ($string, ":", true)); //string (1) "1"
5629 Seção 25.2: Substring
5630 Substring retorna a parte da string especificada pelos parâmetros start e length
5631 var_dump (substr ("Boo", 1)); //string (2) "oo"
5632 Se houver a possibilidade de encontrar strings de caracteres de múltiplos bytes,
seria mais seguro usar mb_substr.
5633 FF
5634 Notas PHP para Profissionais 137
5635 $cake = "bolo ‫;"זרו‬
5636 var_dump (substr ($cake, 0, 5)); //string (5) "bolo".
5637 var_dump (mb_substr ($cake, 0, 5, 'UTF8')); //string (6) "bolo ‫"ז‬
5638 Outra variante é a função substr_replace, que substitui o texto dentro de uma parte
de uma string
5639 var_dump (substr_replace ("Boo", "0", 1, 1)); //string (3) "B0o"
5640 var_dump (substr_Replace ("Boo", "ts", strlen ("Boo"))); //string (5) "Botas"
5641 Digamos que você queira encontrar uma palavra específica em uma string e não queira
usar o Regex
5642 $hi = "Olá mundo!";
5643 $bye = "Adeus Mundo cruel!";
5644 var_dump (strpos ($hi, "")); //int (5)
5645 var_dump (strpos ($bye, "")); //int (7)
5646 var_dump (substr ($hi, 0, strpos ($hi, ""))); //string (5) "Olá"
5647 var_dump (substr ($bye, 1 * (stre ($bye) strpos ($bye, "")))); //string (13) "mundo
cruel!"
5648 //Se a caixa no texto não for importante, o uso do strtolower ajuda a comparar as
strings
5649 var_dump (substr ($hi, 0, strpos ($hi, "")) == 'olá'); //bool (false)
5650 var_dump (strtolower (substr ($hi, 0, strpos ($hi, ""))) == 'olá'); //bool (true)
5651 Outra opção é uma análise muito básica de um email
5652 $email = "test@example.com";
5653 $wrong = "foobar.co.uk";
5654 $notld = "foo @ bar";
5655 $at = strpos ($email, "@"); //int (4)
5656 $wat = strpos ($errado, "@"); //bool (false)
5657 $nat = strpos ($notld, "@"); //int (3)
5658 $domain = substr ($email, $at + 1); //string (11) "example.com"
5659 $womain = substr ($errado, $wat + 1); //string (11) "oobar.co.uk"
5660 $nomain = substr ($notld, $nat + 1); //string (3) "barra"
5661 $dot = strpos ($domain, "."); //int (7)
5662 $wot = strpos ($womain, "."); //int (5)
5663 $not = strpos ($nomain, "."); //bool (false)
5664 $tld = substr ($domain, $dot + 1); //string (3) "com"
5665 $wld = substr ($womain, $wot + 1); //string (5) "co.uk"
5666 $nld = substr ($nomain, $not + 1); //string (2) "ar"
5667 //string (25) "test@example.com é válido"
5668 if ($at && $dot) var_dump ("$email é válido");
5669 else var_dump ("$email é inválido");
5670 //string (21) "foobar.com é inválido"
5671 if ($wat && $wot) var_dump ("$errado é válido");
5672 else var_dump ("$errado é inválido");
5673 //string (18) "foo @ bar é inválido"
5674 if ($nat && $not) var_dump ("$notld é válido");
5675 else var_dump ("$notld é inválido");
5676 //string (27) "foobar.co.uk é um email do Reino Unido"
5677 if ($tld == "co.uk") var_dump ("$email é um endereço no Reino Unido");
5678 FF
5679 Notas PHP para Profissionais 138
5680 if ($wld == "co.uk") var_dump ("$errado é um endereço no Reino Unido");
5681 if ($nld == "co.uk") var_dump ("$notld é um endereço do Reino Unido");
5682 Ou até mesmo colocar o "Continue reading" ou "..." no final de uma sinopse
5683 $blurb = "Lorem ipsum dolor sentese amet";
5684 $limite = 20;
5685 var_dump (substr ($blurb, 0, $limit 3) '...'); //string (20) "Lorem ipsum dolor ..."
5686 Seção 25.3: Pesquisando uma substring com strpos
5687 strpos pode ser entendido como o número de bytes no palheiro antes da primeira
ocorrência da agulha
5688 var_dump (strpos ("palheiro", "feno")); //int (0)
5689 var_dump (strpos ("palheiro", "pilha")); //int (3)
5690 var_dump (strpos ("palheiro", "stackoverflow"); //bool (false)
5691 Verificando se existe uma substring
5692 Tenha cuidado com a verificação contra VERDADEIRO ou FALSO, porque se um índice de 0
for retornado, uma instrução if verá isso como
5693 FALSO
5694 $pos = strpos ("abcd", "a"); //$pos = 0;
5695 $pos2 = strpos ("abcd", "e"); //$pos2 = FALSE;
5696 //Mau exemplo de verificar se uma agulha é encontrada
5697 if ($pos) {//0 não combina com TRUE
5698 echo "1 Eu encontrei sua string \ n";
5699 }
5700 outro {
5701 echo "1 Não encontrei sua string \ n";
5702 }
5703 //Exemplo prático de verificar se a agulha foi encontrada
5704 if ($pos! == FALSE) {
5705 echo "2 Eu encontrei sua string \ n";
5706 }
5707 outro {
5708 echo "2 Eu não encontrei sua string \ n";
5709 }
5710 //Verificando se uma agulha não foi encontrada
5711 if ($pos2 === FALSE) {
5712 echo "3 Eu não encontrei sua string \ n";
5713 }
5714 outro {
5715 echo "3 Eu encontrei sua string \ n";
5716 }
5717 Saída do exemplo inteiro:
5718 1 Eu não encontrei sua string
5719 2 Eu encontrei sua string
5720 3 Eu não encontrei sua string
5721 Pesquisa a partir de um deslocamento
5722 //Com offset podemos procurar ignorando qualquer coisa antes do offset
5723 FF
5724 Notas PHP para Profissionais 139
5725 $needle = "Olá";
5726 $haystack = "Olá, mundo! Olá mundo";
5727 $pos = strpos ($palheiro, $agulha, 1); //$pos = 13, não 0
5728 Obter todas as ocorrências de uma substring
5729 $palheiro = "um bebê, um gato, um burro, um peixe";
5730 $needle = "a";
5731 $offsets = [];
5732 //começa a procurar desde o início da string
5733 para ($offset = 0;
5734 //Se o nosso deslocamento estiver além do alcance do
5735 //string, não pesquise mais
5736 //Se esta condição não estiver definida, um aviso
5737 //ser acionado se $haystack terminar com $needle
5738 //e $needle são apenas um byte de comprimento
5739 $offset <strlen ($palheiro); ) {
5740 $pos = strpos ($palheiro, $agulha, $deslocamento);
5741 //não temos mais substrings
5742 if ($pos === false) quebra;
5743 $offsets [] = $pos;
5744 //Você pode querer adicionar strlen ($needle) em vez disso,
5745 //dependendo se você quer contar "aaa"
5746 //como 1 ou 2 "aa" s
5747 $offset = $pos + 1;
5748 }
5749 echo json_encode ($offsets); //[0,8,15,25]
5750 Seção 25.4: Cadeia de análise usando expressões regulares
5751 preg_match pode ser usado para analisar uma string usando expressões regulares As
partes da expressão entre parênteses
5752 são chamados de subpadrões e com eles você pode escolher partes individuais da string
5753 $str = "<a href=\"http://example.org\"> Meu Link </a>";
5754 $pattern = "/<a href=\"(.*)\"> ( *) <\ /a> /";
5755 $result = preg_match ($padrão, $str, $correspondências);
5756 if ($result === 1) {
5757 //A string corresponde à expressão
5758 print_r ($correspondências);
5759 } else if ($result === 0) {
5760 //Sem correspondência
5761 } outro {
5762 //Ocorreu um erro
5763 }
5764 Saída
5765 Matriz
5766 (
5767 [0] => <a href="http://example.org"> Meu link </a>
5768 [1] => http://example.org
5769 [2] => meu link
5770 )
5771 FF
5772 Notas PHP para Profissionais 140
5773 Capítulo 26: Classes e Objetos
5774 Classes e Objetos são usados para tornar seu código mais eficiente e menos
repetitivo, agrupando tarefas semelhantes
5775 Uma classe é usada para definir as ações e estrutura de dados usadas para construir
objetos Os objetos são então construídos usando este
5776 estrutura predefinida
5777 Seção 26.1: Constantes de Classe
5778 As constantes de classe fornecem um mecanismo para manter valores fixos em um
programa Ou seja, eles fornecem uma maneira de dar um
5779 nome (e verificação associada de tempo de compilação) para um valor como 3.14 ou
"Apple" As constantes de classe só podem ser definidas
5780 com a palavrachave const a função define não pode ser usada neste contexto
5781 Por exemplo, pode ser conveniente ter uma representação abreviada do valor de p ao
longo de um programa
5782 Uma classe com valores constantes fornece uma maneira simples de manter esses valores
5783 class MathValues {
5784 const PI = M_PI;
5785 PHI const = 1,61803;
5786 }
5787 $area = MathValues :: PI * $raio * $raio;
5788 As constantes de classe podem ser acessadas usando o operador de dois pontos
(chamado de operador de resolução de escopo) em um
5789 classe, muito parecido com variáveis estáticas Diferentemente das variáveis
estáticas, no entanto, as constantes de classe têm seus valores fixos na compilação
5790 tempo e não pode ser reatribuído para (por exemplo, MathValues :: PI = 7 produziria
um erro fatal)
5791 As constantes de classe também são úteis para definir as coisas internas de uma
classe que podem precisar ser alteradas posteriormente (mas não
5792 mudar com freqüência suficiente para justificar o armazenamento, digamos, em um
banco de dados) Podemos fazer referência a isso internamente usando o auto
5793 resolutor de escopo (que funciona em implementações instanciadas e estáticas)
5794 trabalho de classe {
5795 /** Quanto tempo, em horas, leva para criar o item? */
5796 const LABOR_UNITS = 0,26;
5797 /** Quanto estamos pagando funcionários por hora? */
5798 const LABOR_COST = 12,75;
5799 função pública getLaborCost ($number_units) {
5800 return (self :: LABOR_UNITS * self :: LABOR_COST) * $number_units;
5801 }
5802 }
5803 Constantes de classe só podem conter valores escalares em versões <5.6
5804 A partir do PHP 5.6 podemos usar expressões com constantes, significando instruções
matemáticas e strings com concatenação
5805 constantes aceitáveis
5806 trabalho de classe {
5807 /** Quanto estamos pagando funcionários por hora? Salários por hora * horas tomadas
para fazer */
5808 const LABOR_COSTS = 12,75 * 0,26;
5809 função pública getLaborCost ($number_units) {
5810 return self :: LABOR_COSTS * $number_units;
5811 }
5812 }
5813 FF
5814 Notas PHP para Profissionais 141
5815 A partir do PHP 7.0, as constantes declaradas com define agora podem conter matrizes
5816 define ("BAZ", array ('baz'));
5817 Constantes de classe são úteis para mais do que simplesmente armazenar conceitos
matemáticos Por exemplo, se preparando uma torta,
5818 Pode ser conveniente ter uma única classe Pie capaz de levar diferentes tipos de
frutas
5819 class Pie {
5820 fruta protegida;
5821 função pública __construct ($fruit) {
5822 $this> fruit = $fruit;
5823 }
5824 }
5825 Podemos então usar a classe Pie assim
5826 $pie = new Pie ("morango");
5827 O problema que surge aqui é, ao instanciar a classe Pie, nenhuma orientação é
fornecida quanto ao aceitável
5828 valores Por exemplo, ao fazer uma torta de "boysenberry", ela pode estar escrita
incorretamente "boisenberry" Além disso, nós
5829 pode não suportar uma torta de ameixa Em vez disso, seria útil ter uma lista de
tipos de frutas aceitáveis já definidos
5830 em algum lugar, faria sentido procurálos Diga uma classe chamada Fruit:
5831 class Fruit {
5832 const APPLE = "maçã";
5833 const MORANGO = "morango";
5834 const BOYSENBERRY = "boysenberry";
5835 }
5836 $pie = new Pie (Fruta: MORANGO);
5837 Listar os valores aceitáveis como constantes de classe fornece uma dica valiosa
sobre os valores aceitáveis que um método
5838 aceita Também garante que erros de ortografia não passem do compilador Enquanto nova
torta ('aple') e nova
5839 Pie ('apple') são ambos aceitáveis para o compilador, o novo Pie (Fruit :: APLE)
produzirá um erro no compilador
5840 Finalmente, usar constantes de classe significa que o valor real da constante pode
ser modificado em um único lugar, e qualquer
5841 código usando a constante automaticamente tem os efeitos da modificação
5842 Embora o método mais comum para acessar uma constante de classe seja MyClass ::
CONSTANT_NAME, ele também pode ser acessado
5843 por:
5844 eco MyClass :: CONSTANTE;
5845 $classname = "MyClass";
5846 echo $classname :: CONSTANT; //A partir do PHP 5.3.0
5847 Constantes de classe no PHP são convencionalmente nomeadas todas em maiúsculas com
sublinhados como separadores de palavras, embora
5848 qualquer nome de rótulo válido pode ser usado como um nome de constante de classe
5849 A partir do PHP 7.1, as constantes de classe podem agora ser definidas com
diferentes visibilidades do escopo público padrão este
5850 significa que as constantes protegidas e privadas agora podem ser definidas para
evitar constantes de classe desnecessariamente
5851 vazando para o escopo público (consulte Método e Visibilidade da propriedade) Por
exemplo:
5852 class Algo {
5853 const PUBLIC_CONST_A = 1;
5854 FF
5855 Notas PHP para Profissionais 142
5856 public const PUBLIC_CONST_B = 2;
5857 protected const PROTECTED_CONST = 3;
5858 private const PRIVATE_CONST = 4;
5859 }
5860 definir as constantes de classe vs
5861 Embora esta seja uma construção válida:
5862 barra de funções () {return 2; };
5863 define ('BAR', bar ());
5864 Se você tentar fazer o mesmo com as constantes de classe, receberá um erro:
5865 barra de funções () {return 2; };
5866 class Foo {
5867 const BAR = bar (); //Erro: a expressão constante contém operações inválidas
5868 }
5869 Mas você pode fazer:
5870 barra de funções () {return 2; };
5871 define ('BAR', bar ());
5872 class Foo {
5873 const BAR = BAR; //ESTÁ BEM
5874 }
5875 Para mais informações, consulte as constantes no manual
5876 Usando :: class para recuperar o nome da classe
5877 O PHP 5.5 introduziu a sintaxe :: class para recuperar o nome completo da classe,
tomando o escopo do namespace e instruções de uso
5878 em conta
5879 namespace foo;
5880 use bar \ Bar;
5881 echo json_encode (barra :: classe); //"bar \\ Bar"
5882 echo json_encode (Foo :: class); //"foo \\ Foo"
5883 echo json_encode (\ Foo :: class); //"Foo"
5884 O acima funciona mesmo que as classes não estejam definidas (isto é, este snippet de
código funciona sozinho)
5885 Essa sintaxe é útil para funções que exigem um nome de classe Por exemplo, ele pode
ser usado com class_exists para
5886 verifique se existe uma classe Nenhum erro será gerado, independentemente do valor
de retorno neste snippet:
5887 class_exists (ThisClass \ Será \ NeverBe \ Loaded :: class, false);
5888 Seção 26.2: Classes Abstratas
5889 Uma classe abstrata é uma classe que não pode ser instanciada As classes abstratas
podem definir métodos abstratos, que são
5890 métodos sem qualquer corpo, apenas uma definição:
5891 classe abstrata MyAbstractClass {
5892 FF
5893 Notas PHP para Profissionais 143
5894 função pública abstrata doSomething ($a, $b);
5895 }
5896 Classes abstratas devem ser estendidas por uma classe de crianças, a qual pode então
fornecer a implementação destas
5897 métodos
5898 O objetivo principal de uma classe como essa é fornecer um tipo de modelo que
permita que classes de crianças herdem,
5899 "forçando" uma estrutura a aderir Vamos elaborar sobre isso com um exemplo:
5900 Neste exemplo, vamos implementar uma interface de trabalho Primeiro nós definimos a
interface:
5901 Trabalhador de interface {
5902 função pública run ();
5903 }
5904 Para facilitar o desenvolvimento de outras implementações do Worker, criaremos uma
classe de trabalho abstrata que já
5905 fornece o método run () da interface, mas especifica alguns métodos abstratos que
precisam ser preenchidos por qualquer
5906 classe infantil:
5907 classe abstrata AbstractWorker implementa Trabalhador {
5908 protegido $pdo;
5909 protegido $logger;
5910 função pública __construct (PDO $pdo, Logger $logger) {
5911 $this> pdo = $pdo;
5912 $this> logger = $logger;
5913 }
5914 função pública run () {
5915 experimentar {
5916 $this> setMemoryLimit ($this> getMemoryLimit ());
5917 $this> logger> log ("Preparando main");
5918 $this> prepareMain ();
5919 $this> logger> log ("Executando main");
5920 $this> main ();
5921 } pegar (Throwable $e) {
5922 //Captura e relançam todos os erros para que possam ser registrados pelo worker
5923 $this> logger> log ("Falha do worker com exceção: {$e> getMessage ()}");
5924 jogar $e;
5925 }
5926 }
5927 função privada setMemoryLimit ($memoryLimit) {
5928 ini_set ('memory_limit', $memoryLimit);
5929 $this> logger> log ("Definir limite de memória para $memoryLimit");
5930 }
5931 função protegida abstrata getMemoryLimit ();
5932 função protegida abstrata prepareMain ();
5933 função protegida abstrata main ();
5934 }
5935 Primeiro de tudo, nós fornecemos um método abstrato getMemoryLimit () Qualquer
classe que se estende do AbstractWorker
5936 precisa fornecer esse método e retornar seu limite de memória O AbstractWorker, em
seguida, define o limite de memória e
5937 registra
5938 Em segundo lugar, o AbstractWorker chama os métodos prepareMain () e main (), depois
de registrar que eles foram
5939 FF
5940 Notas PHP para Profissionais 144
5941 chamado
5942 Finalmente, todas essas chamadas de método foram agrupadas em um bloco trycatch
Então, se algum dos métodos abstratos definidos
5943 pela classe filha lança uma exceção, nós pegaremos essa exceção, registrea e volte a
colocála Isso evita que toda criança
5944 classes de ter que implementar isso sozinhos
5945 Agora vamos definir uma classe filha que se estende a partir do AbstractWorker:
5946 classe TranscactionProcessorWorker estende AbstractWorker {
5947 transações $privadas;
5948 função protegida getMemoryLimit () {
5949 devolve "512M";
5950 }
5951 função protegida prepareMain () {
5952 $stmt = $this> pdo> query ("SELECIONE * DE transações WHERE processado = 0 LIMITE
500");
5953 $stmt> execute ();
5954 $this> transactions = $stmt> fetchAll ();
5955 }
5956 função protegida main () {
5957 foreach ($this> transações como $transaction) {
5958 //Poderia lançar alguma exceção PDO ou MYSQL, mas isso é tratado pelo AbstractWorker
5959 $stmt = $this> pdo> query ("transações UPDATE SET processado = 1 WHERE id =
5960 {$transaction ['id']} LIMITE 1 ");
5961 $stmt> execute ();
5962 }
5963 }
5964 }
5965 Como você pode ver, o TransactionProcessorWorker foi bastante fácil de implementar,
já que precisávamos apenas especificar
5966 limite de memória e se preocupar com as ações reais que ele precisava executar
Nenhum tratamento de erros é necessário no
5967 TransactionProcessorWorker porque isso é tratado no AbsractWorker
5968 Nota importante
5969 Ao herdar de uma classe abstrata, todos os métodos marcados como abstract na
declaração de classe pai
5970 deve ser definido pela criança (ou a própria criança também deve ser marcada como
abstrata); adicionalmente, esses
5971 Os métodos devem ser definidos com a mesma visibilidade (ou menos restrita) Por
exemplo, se o resumo
5972 método é definido como protegido, a implementação da função deve ser definida como
protegida ou
5973 público, mas não privado
5974 Extraído da documentação do PHP para abstração de classe
5975 Se você não definir os métodos de classes abstratas pai dentro da classe filha, você
será lançado um PHP Fatal
5976 Erro como o seguinte
5977 Erro fatal: Classe X contém 1 método abstrato e, portanto, deve ser declarado como
abstrato ou implementar
5978 os restantes métodos (X :: x) em
5979 Seção 26.3: Ligação estática atrasada
5980 No PHP 5.3+ e acima, você pode utilizar a ligação estática tardia para controlar a
qual classe uma propriedade ou método estático é chamado
5981 FF
5982 Notas PHP para Profissionais 145
5983 de Foi adicionado para superar o problema inerente ao resolutor self :: scope Tome o
seguinte código
5984 class Horse {
5985 função estática pública whatToSay () {
5986 eco 'Neigh!';
5987 }
5988 função estática pública speak () {
5989 self :: whatToSay ();
5990 }
5991 }
5992 classe MrEd estende o cavalo {
5993 função estática pública whatToSay () {
5994 eco 'Olá Wilbur!';
5995 }
5996 }
5997 Você esperaria que a classe MrEd substituísse a função pai whatToSay () Mas quando
corremos, conseguimos
5998 algo inesperado
5999 Cavalo :: fala (); //Neigh!
6000 MrEd :: speak (); //Neigh!
6001 O problema é que self :: whatToSay (); só pode se referir à classe Horse, o que
significa que não obedece a MrEd Se nós
6002 mudar para o resolutor static :: scope, não temos esse problema Este método mais
recente diz à classe para obedecer
6003 exemplo chamandoo Assim, temos a herança que estamos esperando
6004 class Horse {
6005 função estática pública whatToSay () {
6006 eco 'Neigh!';
6007 }
6008 função estática pública speak () {
6009 static :: whatToSay (); //Ligação estática atrasada
6010 }
6011 }
6012 Cavalo :: fala (); //Neigh!
6013 MrEd :: speak (); //Olá Wilbur!
6014 Seção 26.4: Espaçamento de Nomes e Carregamento Automático
6015 Tecnicamente, o carregamento automático funciona executando um callback quando uma
classe PHP é requerida, mas não encontrada Tais retornos de chamada
6016 geralmente tentam carregar essas classes
6017 Geralmente, autoloading pode ser entendido como a tentativa de carregar arquivos PHP
(especialmente arquivos de classe PHP, onde um PHP
6018 arquivo de origem é dedicado para uma classe específica) de caminhos apropriados de
acordo com o nome completo da classe
6019 (FQN) quando uma aula é necessária
6020 Suponha que tenhamos essas classes:
6021 Arquivo de classe para application \ controllers \ Base:
6022 <?php
6023 aplicação namespace \ controllers {class Base {...}}
6024 FF
6025 Notas PHP para Profissionais 146
6026 Arquivo de classe para application \ controllers \ Control:
6027 <?php
6028 aplicativo de namespace \ controllers {controle de classe {...}}
6029 Arquivo de classe para o aplicativo \ models \ Page:
6030 <?php
6031 aplicação namespace \ models {class Page {...}}
6032 Sob a pasta de origem, essas classes devem ser colocadas nos caminhos como seus FQNs
respectivamente:
6033 Pasta de origem
6034 aplicações
6035 controladores
6036 Base.php
6037 Control.php
6038 modelos
6039 Page.php
6040 Esta abordagem torna possível resolver programaticamente o caminho do arquivo de
classe de acordo com o FQN, usando este
6041 função:
6042 function getClassPath (string $sourceFolder, string $className, string $extension =
".php") {
6043 return $sourceFolder "/" str_replace ("\\", "/", $className) extensão $; //Observe
que "/"
6044 funciona como um separador de diretórios mesmo no Windows
6045 }
6046 A função spl_autoload_register nos permite carregar uma classe quando necessário
usando uma função definida pelo usuário:
6047 const SOURCE_FOLDER = __DIR__ "/src";
6048 spl_autoload_register (function (string $className) {
6049 $file = getClassPath (SOURCE_FOLDER, $className);
6050 if (is_readable ($file)) arquivo require_once $;
6051 });
6052 Essa função pode ser estendida ainda mais para usar métodos de fallback de
carregamento:
6053 const SOURCE_FOLDERS = [__DIR__ "/src", "/root /src"]);
6054 spl_autoload_register (function (string $className) {
6055 foreach (SOURCE_FOLDERS como $folder) {
6056 $extensions = [
6057 //temos src /Foo /Bar.php5_int64?
6058 ".php" PHP_MAJOR_VERSION "_int" (PHP_INT_SIZE * 8),
6059 //temos src /Foo /Bar.php7?
6060 ".php" PHP_MAJOR_VERSION,
6061 //temos src /Foo /Bar.php_int64?
6062 ".php" "_int" (PHP_INT_SIZE * 8),
6063 //temos src /Foo /Bar.phps?
6064 ".phps"
6065 //temos src /Foo /Bar.php?
6066 ".php"
6067 ];
6068 foreach ($extensions as $ext) {
6069 $path = getClassPath (pasta $, $className, $extensão);
6070 if (is_readable ($path)) retorna $caminho;
6071 }
6072 FF
6073 Notas PHP para Profissionais 147
6074 }
6075 });
6076 Note que o PHP não tenta carregar as classes sempre que um arquivo que usa esta
classe é carregado Pode ser carregado em
6077 no meio de um script, ou mesmo em funções de desligamento Esta é uma das razões
pelas quais os desenvolvedores, especialmente aqueles
6078 Quem usa o autoloading, deve evitar substituir a execução de arquivos de origem no
tempo de execução, especialmente em arquivos phar
6079 Seção 26.5: Método e visibilidade da propriedade
6080 Existem três tipos de visibilidade que você pode aplicar a métodos (funções de
classe /objeto) e propriedades (classe /objeto
6081 variáveis) dentro de uma classe, que fornecem controle de acesso para o método ou
propriedade para o qual são aplicadas
6082 Você pode ler extensivamente sobre isso na Documentação PHP para Visibilidade de OOP
6083 Público
6084 Declarar um método ou uma propriedade como public permite que o método ou a
propriedade seja acessada por:
6085 A classe que declarou isso
6086 As classes que estendem a classe declarada
6087 Quaisquer objetos externos, classes ou códigos fora da hierarquia de classes
6088 Um exemplo desse acesso público seria:
6089 class MyClass {
6090 //Propriedade
6091 public $myProperty = 'teste';
6092 //Method
6093 Função pública myMethod () {
6094 return $this> myProperty;
6095 }
6096 }
6097 $obj = new MyClass ();
6098 echo $obj> myMethod ();
6099 //Out: teste
6100 echo $obj> myProperty;
6101 //Out: teste
6102 Protegido
6103 Declarar um método ou uma propriedade como protegida permite que o método ou a
propriedade seja acessado por:
6104 A classe que declarou isso
6105 As classes que estendem a classe declarada
6106 Isso não permite que objetos externos, classes ou códigos fora da hierarquia de
classes acessem esses métodos ou
6107 propriedades Se algo usando este método /propriedade não tiver acesso a ele, ele não
estará disponível e um erro
6108 será lançado Apenas instâncias do self declarado (ou suas subclasses) têm acesso a
ele.
6109 Um exemplo desse acesso protegido seria:
6110 class MyClass {
6111 protected $myProperty = 'teste';
6112 FF
6113 Notas PHP para Profissionais 148
6114 função protegida myMethod () {
6115 return $this> myProperty;
6116 }
6117 }
6118 classe MySubClass estende MyClass {
6119 função pública run () {
6120 echo $this> myMethod ();
6121 }
6122 }
6123 $obj = new MySubClass ();
6124 $obj> run (); //Isso chamará MyClass :: myMethod ();
6125 //Out: teste
6126 $obj> myMethod (); //Isso irá falhar.
6127 //Out: Erro fatal: Chame para o método protegido MyClass :: myMethod () do contexto
''
6128 O exemplo acima observa que você só pode acessar os elementos protegidos dentro de
seu próprio escopo Essencialmente: "O que há
6129 a casa só pode ser acessada de dentro da casa "
6130 Privado
6131 Declarar um método ou uma propriedade como privada permite que o método ou a
propriedade seja acessado por:
6132 A classe que declarou apenas (não subclasses)
6133 Um método ou uma propriedade privada é visível e acessível somente dentro da classe
que a criou
6134 Observe que objetos do mesmo tipo terão acesso a membros privados e protegidos uns
dos outros, embora
6135 eles não são os mesmos casos
6136 class MyClass {
6137 private $myProperty = 'teste';
6138 função privada myPrivateMethod () {
6139 return $this> myProperty;
6140 }
6141 Função pública myPublicMethod () {
6142 return $this> myPrivateMethod ();
6143 }
6144 função pública modifyPrivatePropertyOf (MyClass $anotherInstance) {
6145 $anotherInstance> myProperty = "novo valor";
6146 }
6147 }
6148 classe MySubClass estende MyClass {
6149 função pública run () {
6150 echo $this> myPublicMethod ();
6151 }
6152 função pública runWithPrivate () {
6153 echo $t his> myPrivateMethod ();
6154 }
6155 }
6156 $obj = new MySubClass ();
6157 FF
6158 Notas PHP para Profissionais 149
6159 $newObj = new MySubClass ();
6160 //Isso chamará MyClass :: myPublicMethod (), que então chamará
6161 //MyClass :: myPrivateMethod ();
6162 $obj> run ();
6163 //Out: teste
6164 $obj> modifyPrivatePropertyOf ($newObj);
6165 $newObj> run ();
6166 //Out: novo valor
6167 echo $obj> myPrivateMethod (); //Isso irá falhar.
6168 //Out: Erro fatal: Chame para o método privado MyClass :: myPrivateMethod () do
contexto ''
6169 echo $obj> runWithPrivate (); //Isso também falhará.
6170 //Out: Erro fatal: Chame para o método privado MyClass :: myPrivateMethod () do
contexto 'MySubClass'
6171 Como observado, você só pode acessar o método /propriedade particular de dentro de
sua classe definida
6172 Seção 26.6: Interfaces
6173 Introdução
6174 Interfaces são definições das classes de APIs públicas que devem ser implementadas
para satisfazer a interface Eles funcionam como
6175 "contratos", especificando o que um conjunto de subclasses faz, mas não como eles
fazem isso
6176 A definição da interface é muito parecida com a definição de classe, alterando a
classe da palavrachave para a interface:
6177 interface Foo {
6178 }
6179 Interfaces podem conter métodos e /ou constantes, mas sem atributos As constantes da
interface têm as mesmas restrições
6180 como constantes de classe Os métodos de interface são implicitamente abstratos:
6181 interface Foo {
6182 const BAR = 'BAR';
6183 função pública doSomething ($param1, $param2);
6184 }
6185 Nota: as interfaces não devem declarar construtores ou destruidores, já que estes
são detalhes de implementação na classe
6186 nível
6187 Realização
6188 Qualquer classe que precise implementar uma interface deve fazer isso usando a
palavrachave implements Para fazer isso, a turma
6189 precisa fornecer uma implementação para cada método declarado na interface,
respeitando a mesma assinatura
6190 Uma única classe pode implementar mais de uma interface por vez
6191 interface Foo {
6192 função pública doSomething ($param1, $param2);
6193 }
6194 barra de interface {
6195 FF
6196 Notas PHP para Profissionais 150
6197 função pública doAnotherThing ($param1);
6198 }
6199 classe Baz implementa Foo, Bar {
6200 função pública doSomething ($param1, $param2) {
6201 //.
6202 }
6203 função pública doAnotherThing ($param1) {
6204 //.
6205 }
6206 }
6207 Quando classes abstratas implementam interfaces, elas não precisam implementar todos
os métodos Qualquer método não
6208 implementado na classe base deve então ser implementado pela classe concreta que o
estende:
6209 classe abstrata AbstractBaz implementa Foo, Bar {
6210 //Implementação parcial da interface requerida .
6211 função pública doSomething ($param1, $param2) {
6212 //.
6213 }
6214 }
6215 classe Baz estende AbstractBaz {
6216 função pública doAnotherThing ($param1) {
6217 //.
6218 }
6219 }
6220 Observe que a realização da interface é uma característica herdada Ao estender uma
classe que implementa uma interface,
6221 você não precisa redeclarálo na classe concreta, porque é implícito
6222 Nota: Antes do PHP 5.3.9, uma classe não podia implementar duas interfaces que
especificassem um método com o
6223 mesmo nome, pois causaria ambiguidade Versões mais recentes do PHP permitem isso
desde que o
6224 os métodos duplicados têm a mesma assinatura [1]
6225 Herança
6226 Como as classes, é possível estabelecer um relacionamento de herança entre
interfaces, usando a mesma palavrachave
6227 estendese A principal diferença é que herança múltipla é permitida para interfaces:
6228 interface Foo {
6229 }
6230 barra de interface {
6231 }
6232 interface Baz estende Foo, Bar {
6233 }
6234 Exemplos
6235 No exemplo abaixo, temos uma interface de exemplo simples para um veículo Veículos
podem ir para frente e para trás.
6236 FF
6237 Notas PHP para Profissionais 151
6238 interface VehicleInterface {
6239 função pública para a frente ();
6240 função pública reversa ();
6241 .
6242 }
6243 A classe Bike implementa VehicleInterface {
6244 função pública forward () {
6245 $this> pedal ();
6246 }
6247 função pública reverse () {
6248 $this> backwardSteps ();
6249 }
6250 pedal de função protegido () {
6251 .
6252 }
6253 função protegida backwardSteps () {
6254 .
6255 }
6256 .
6257 }
6258 class Car implementa VehicleInterface {
6259 protected $gear = 'N';
6260 função pública forward () {
6261 $this> setGear (1);
6262 $this> pushPedal ();
6263 }
6264 função pública reverse () {
6265 $this> setGear ('R');
6266 $this> pushPedal ();
6267 }
6268 função protegida setGear ($gear) {
6269 $this> gear = $gear;
6270 }
6271 função protegida pushPedal () {
6272 .
6273 }
6274 .
6275 }
6276 Então criamos duas classes que implementam a interface: Bike e Car Bicicleta e carro
internamente são muito diferentes,
6277 mas ambos são veículos e devem implementar os mesmos métodos públicos que o
VehicleInterface fornece
6278 Typehinting permite que métodos e funções solicitem Interfaces Vamos supor que temos
uma aula de garagem,
6279 que contém veículos de todos os tipos
6280 classe ParkingGarage {
6281 $veículos protegidos = [];
6282 FF
6283 Notas PHP para Profissionais 152
6284 public function addVehicle (VehicleInterface $vehicle) {
6285 $this> vehicles [] = $veículo;
6286 }
6287 }
6288 Como addVehicle requer um veículo $do tipo VehicleInterface não uma implementação
concreta podemos
6289 insira tanto Bikes como Cars, que o ParkingGarage pode manipular e usar
6290 Seção 26.7: Palavrachave final
6291 Def: Final Keyword impede classes subordinadas de sobrescrever um método prefixando
a definição com final Se a turma
6292 em si está sendo definido final, então não pode ser estendido
6293 Método final
6294 classe BaseClass {
6295 teste de função pública () {
6296 echo "BaseClass :: test () chamado \ n";
6297 }
6298 função pública final moreTesting () {
6299 echo "BaseClass :: moreTesting () chamado \ n";
6300 }
6301 }
6302 classe ChildClass estende BaseClass {
6303 função pública moreTesting () {
6304 echo "ChildClass :: moreTesting () chamado \ n";
6305 }
6306 }
6307 //Resulta em erro fatal: não é possível substituir o método final BaseClass ::
moreTesting ()
6308 Classe final:
6309 classe final BaseClass {
6310 teste de função pública () {
6311 echo "BaseClass :: test () chamado \ n";
6312 }
6313 //Aqui não importa se você especifica a função como final ou não
6314 função pública final moreTesting () {
6315 echo "BaseClass :: moreTesting () chamado \ n";
6316 }
6317 }
6318 classe ChildClass estende BaseClass {
6319 }
6320 //Resulta em erro fatal: Class ChildClass não pode herdar da classe final (BaseClass)
6321 Constantes finais: Ao contrário de Java, a palavrachave final não é usada para
constantes de classe no PHP Use a palavra chave const
6322 em vez de
6323 Por que eu tenho que usar final?
6324 1 Impedindo a cadeia de herança maciça da desgraça
6325 2 Incentivar a composição
6326 3 Force o desenvolvedor a pensar na API pública do usuário
6327 4 Force o desenvolvedor a encolher a API pública de um objeto
6328 FF
6329 Notas PHP para Profissionais 153
6330 5 Uma aula final sempre pode ser feita extensível
6331 6 estende o encapsulamento de quebras
6332 7 Você não precisa dessa flexibilidade
6333 8 Você é livre para mudar o código
6334 Quando evitar final: As aulas finais só funcionam de forma eficaz seguindo as
seguintes suposições:
6335 1 Existe uma abstração (interface) que a classe final implementa
6336 2 Toda a API pública da classe final faz parte dessa interface
6337 Seção 26.8: Carregamento automático
6338 Ninguém quer exigir ou incluir toda vez que uma classe ou herança é usada Porque
pode ser doloroso e é fácil
6339 para esquecer, o PHP está oferecendo o chamado autoloading Se você já estiver usando
o Composer, leia sobre o carregamento automático usando
6340 Compositor
6341 O que exatamente é o carregamento automático?
6342 O nome basicamente diz tudo Você não precisa obter o arquivo no qual a classe
solicitada está armazenada, mas o PHP
6343 carregao automaticamente
6344 Como posso fazer isso no PHP básico sem código de terceiros?
6345 Existe a função __autoload, mas é considerado melhor prática usar
spl_autoload_register Estes
6346 funções serão consideradas pelo PHP toda vez que uma classe não for definida dentro
do espaço dado Então, adicionando autoload para
6347 um projeto existente não é problema, pois classes definidas (via require ie)
funcionarão como antes Por uma questão de
6348 preciseness, os seguintes exemplos usarão funções anônimas, se você usar PHP <5.3,
você pode definir a função
6349 e passe seu nome como argumento para spl_autoload_register
6350 Exemplos
6351 spl_autoload_register (function ($className) {
6352 $path = sprintf ('% s.php', $className);
6353 if (file_exists ($path)) {
6354 inclua $caminho;
6355 } outro {
6356 //arquivo não encontrado
6357 }
6358 });
6359 O código acima simplesmente tenta incluir um nome de arquivo com o nome da classe e
a extensão anexada ".php" usando
6360 sprintf Se o FooBar precisar ser carregado, ele parecerá se o FooBar.php existe e se
ele o inclui.
6361 Claro que isso pode ser estendido para atender às necessidades individuais do
projeto Se _ dentro de um nome de classe é usado para agrupar, por exemplo
6362 User_Post e User_Image se referem ao usuário, ambas as classes podem ser mantidas em
uma pasta chamada "User" assim:
6363 spl_autoload_register (function ($className) {
6364 //substitua _ por /ou \ (dependendo do sistema operacional)
6365 $path = sprintf ('% s.php', str_replace ('_', DIRECTORY_SEPARATOR, $className));
6366 if (file_exists ($path)) {
6367 inclua $caminho;
6368 } outro {
6369 //arquivo não encontrado
6370 }
6371 });
6372 FF
6373 Notas PHP para Profissionais 154
6374 A classe User_Post será agora carregada de "User /Post.php", etc
6375 O spl_autoload_register pode ser adaptado para várias necessidades Todos os seus
arquivos com classes são nomeados
6376 "class.CLASSNAME.php"? Sem problemas Vários aninhamentos (User_Post_Content => "User
/Post /Content.php")? Não
6377 problema também
6378 Se você quer um mecanismo de autoloading mais elaborado e ainda não quer incluir o
Composer você pode trabalhar
6379 sem adicionar bibliotecas de terceiros
6380 spl_autoload_register (function ($className) {
6381 $path = sprintf ('% 1 $s% 2 $s% 3 $s.php',
6382 //% 1 $s: obter caminho absoluto
6383 caminho real (dirname (__ FILE__)),
6384 //% 2 $s: /ou \ (dependendo do sistema operacional)
6385 DIRECTORY_SEPARATOR,
6386 //% 3 $s: não se preocupe com limites ou não ao criar os arquivos
6387 strtolower (
6388 //substitua _ por /ou \ (dependendo do sistema operacional)
6389 str_replace ('_', DIRECTORY_SEPARATOR, $className)
6390 )
6391 );
6392 if (file_exists ($path)) {
6393 inclua $caminho;
6394 } outro {
6395 lançar nova exceção (
6396 sprintf ('Classe com o nome% 1 $s não encontrado Procurado em% 2 $s.',
6397 $className,
6398 caminho $
6399 )
6400 );
6401 }
6402 });
6403 Usando carregadores automáticos como este, você pode escrever um código como este:
6404 require_once './autoload.php'; //onde spl_autoload_register é definido
6405 $foo = new Foo_Bar (novo Hello_World ());
6406 Usando classes:
6407 classe Foo_Bar estende Foo {}
6408 classe Hello_World implementa Demo_Classes {}
6409 Estes exemplos incluirão classes de foo /bar.php, foo.php, hello /world.php e demo
/classes.php
6410 Seção 26.9: Chamando um construtor pai ao instanciar
6411 uma criança
6412 Uma armadilha comum de classes filhas é que, se seu pai e filho contiverem um
construtor (__ construct ())
6413 método, somente o construtor de classe filho será executado Pode haver ocasiões em
que você precisa executar o pai
6414 método __construct () de seu filho Se você precisa fazer isso, então você precisará
usar o parent :: scope
6415 resolutor:
6416 parent :: __ construct ();
6417 FF
6418 Notas PHP para Profissionais 155
6419 Agora, aproveitando que dentro de uma situação do mundo real seria algo como:
6420 class Foo {
6421 function __construct ($args) {
6422 eco 'pai';
6423 }
6424 }
6425 barra de classe estende Foo {
6426 function __construct ($args) {
6427 parent :: __ construct ($args);
6428 }
6429 }
6430 O acima irá executar o pai __construct () resultando no eco sendo executado
6431 Seção 26.10: Encadernação Dinâmica
6432 A ligação dinâmica, também referida como sobreposição de método, é um exemplo de
polimorfismo de tempo de execução que ocorre quando
6433 várias classes contêm implementações diferentes do mesmo método, mas o objeto que o
método será
6434 chamado é desconhecido até o tempo de execução
6435 Isso é útil se uma determinada condição determinar qual classe será usada para
executar uma ação, em que a ação é denominada
6436 o mesmo em ambas as classes
6437 animal da interface {
6438 função pública makeNoise ();
6439 }
6440 classe Cat implementa Animal {
6441 função pública makeNoise
6442 {
6443 $this> meow ();
6444 }
6445 .
6446 }
6447 class Dog implementa Animal {
6448 função pública makeNoise {
6449 $this> bark ();
6450 }
6451 .
6452 }
6453 class Person {
6454 const CAT = 'gato';
6455 const DOG = 'cachorro';
6456 private $petPreference;
6457 private $pet;
6458 função pública isCatLover (): bool {
6459 return $this> petPreference == self :: CAT;
6460 }
6461 função pública isDogLover (): bool {
6462 FF
6463 Notas PHP para Profissionais 156
6464 return $this> petPreference == self :: DOG;
6465 }
6466 setPet de função pública (Animal $pet) {
6467 $this> pet = $pet;
6468 }
6469 public function getPet (): Animal {
6470 devolve $this> pet;
6471 }
6472 }
6473 if ($person> isCatLover ()) {
6474 $person> setPet (novo Cat ());
6475 } else if ($person> isDogLover ()) {
6476 $person> setPet (new Dog ());
6477 }
6478 $person> getPet () > makeNoise ();
6479 No exemplo acima, a classe Animal (Dog | Cat) que fará o Noise é desconhecida até o
tempo de execução dependendo do
6480 propriedade dentro da classe User
6481 Seção 26.11: $this, self e static mais o singleton
6482 Use $this para se referir ao objeto atual Use auto para se referir à classe atual Em
outras palavras, use
6483 $this> membro para membros não estáticos, use self :: $member para membros estáticos
6484 No exemplo abaixo, sayHello () e sayGoodbye () estão usando self e $essa diferença
pode ser observada aqui
6485 class Person {
6486 nome $privado;
6487 função pública __construct ($name) {
6488 $this> name = $name;
6489 }
6490 função pública getName () {
6491 return $this> name;
6492 }
6493 função pública getTitle () {
6494 retorne $this> getName () "a pessoa";
6495 }
6496 função pública sayHello () {
6497 echo "Olá, eu sou" $this> getTitle () "<br/>";
6498 }
6499 função pública sayGoodbye () {
6500 echo "Adeus de" .self :: getTitle () "<br/>";
6501 }
6502 }
6503 classe Geek estende a pessoa {
6504 função pública __construct ($name) {
6505 parent :: __ construct ($name);
6506 }
6507 FF
6508 Notas PHP para Profissionais 157
6509 função pública getTitle () {
6510 retorne $this> getName () "o geek";
6511 }
6512 }
6513 $geekObj = new Geek ("Ludwig");
6514 $geekObj> sayHello ();
6515 $geekObj> sayGoodbye ();
6516 static referese a qualquer classe na hierarquia na qual você chamou o método Permite
uma melhor reutilização da classe estática
6517 propriedades quando as classes são herdadas
6518 Considere o seguinte código:
6519 classe carro {
6520 marca $estática protegida = 'desconhecido';
6521 marca de função estática pública () {
6522 return self :: $brand "\ n";
6523 }
6524 }
6525 classe Mercedes estende carro {
6526 marca $estática protegida = 'Mercedes';
6527 }
6528 classe BMW estende carro {
6529 marca $estática protegida = 'BMW';
6530 }
6531 eco (carro novo) > marca ();
6532 eco (novo BMW) > marca ();
6533 eco (novo Mercedes) > marca ();
6534 Isso não produz o resultado desejado:
6535 desconhecido
6536 desconhecido
6537 desconhecido
6538 Isso porque auto referese à classe Car sempre que o método brand () é chamado
6539 Para se referir à classe correta, você precisa usar static:
6540 classe carro {
6541 marca $estática protegida = 'desconhecido';
6542 marca de função estática pública () {
6543 return static :: $brand "\ n";
6544 }
6545 }
6546 classe Mercedes estende carro {
6547 marca $estática protegida = 'Mercedes';
6548 }
6549 classe BMW estende carro {
6550 marca $estática protegida = 'BMW';
6551 FF
6552 Notas PHP para Profissionais 158
6553 }
6554 eco (carro novo) > marca ();
6555 eco (novo BMW) > marca ();
6556 eco (novo Mercedes) > marca ();
6557 Isso produz a saída desejada:
6558 desconhecido
6559 BMW
6560 Mercedes
6561 Consulte também Ligação estática atrasada
6562 O singleton
6563 Se você tem um objeto caro para criar ou representa uma conexão com algum recurso
externo que você deseja
6564 reutilização, ou seja, uma conexão de banco de dados onde não há conexão pool ou um
soquete para algum outro sistema, você pode
6565 use as palavraschave estáticas e autônomas em uma classe para tornálo um singleton
Há fortes opiniões sobre se o
6566 padrão singleton deve ou não deve ser usado, mas tem seus usos
6567 classe Singleton {
6568 private static $instance = null;
6569 public static function getInstance () {
6570 if (! isset (self :: $instance)) {
6571 self :: $instance = new self ();
6572 }
6573 return self :: $instance;
6574 }
6575 função privada __construct () {
6576 //Do constructor stuff
6577 }
6578 }
6579 Como você pode ver no código de exemplo, estamos definindo uma propriedade estática
privada $instance para manter o objeto
6580 referência Como isso é estático, essa referência é compartilhada em TODOS os objetos
desse tipo.
6581 O método getInstance () usa um método conhecido como instanciação lenta para atrasar
a criação do objeto até o último
6582 possível momento como você não quer ter objetos não utilizados em torno da memória
nunca pretendeu ser usado isto
6583 também economiza tempo e CPU no carregamento da página, não tendo que carregar mais
objetos do que o necessário O método está verificando se
6584 o objeto é definido, criandoo se não, e retornandoo Isso garante que apenas um
objeto desse tipo seja criado.
6585 Também estamos definindo o construtor para ser privado para garantir que ninguém o
crie com a nova palavrachave do
6586 lado de fora Se você precisar herdar dessa classe, apenas altere as palavraschave
privadas para protected.
6587 Para usar este objeto, basta escrever o seguinte:
6588 $singleton = Singleton :: getInstance ();
6589 Agora eu te imploro para usar injeção de dependência onde você pode e apontar para
objetos fracamente acoplados, mas
6590 às vezes isso não é razoável e o padrão singleton pode ser útil.
6591 FF
6592 Notas PHP para Profissionais 159
6593 Seção 26.12: Definindo uma classe básica
6594 Um objeto no PHP contém variáveis e funções Objetos tipicamente pertencem a uma
classe, que define as variáveis
6595 e funções que todos os objetos desta classe conterão
6596 A sintaxe para definir uma classe é:
6597 class Shape {
6598 public $sides = 0;
6599 descrição da função pública () {
6600 return "Uma forma com $this> lados laterais.";
6601 }
6602 }
6603 Quando uma classe é definida, você pode criar uma instância usando:
6604 $myShape = new Shape ();
6605 Variáveis e funções no objeto são acessadas assim:
6606 $myShape = new Shape ();
6607 $myShape> sides = 6;
6608 print $myShape> descrição (); //"Uma forma com 6 lados"
6609 Construtor
6610 As classes podem definir um método especial __construct (), que é executado como
parte da criação do objeto Isso é freqüentemente usado
6611 para especificar os valores iniciais de um objeto:
6612 class Shape {
6613 public $sides = 0;
6614 função pública __construct ($sides) {
6615 $this> sides = $lados;
6616 }
6617 descrição da função pública () {
6618 return "Uma forma com $this> lados laterais.";
6619 }
6620 }
6621 $myShape = new Shape (6);
6622 print $myShape> descrição (); //Uma forma com 6 lados
6623 Estendendo Outra Classe
6624 As definições de classe podem estender as definições de classe existentes,
adicionando novas variáveis e funções, bem como modificando
6625 aqueles definidos na classe pai
6626 Aqui está uma classe que estende o exemplo anterior:
6627 class Square estende Shape {
6628 public $sideLength = 0;
6629 função pública __construct ($sideLength) {
6630 parent :: __ construct (4);
6631 FF
6632 Notas PHP para Profissionais 160
6633 $this> sideLength = $sideLength;
6634 }
6635 perímetro de função pública () {
6636 retorne $this> sides * $this> sideLength;
6637 }
6638 área de função pública () {
6639 return $this> sideLength * $this> sideLength;
6640 }
6641 }
6642 A classe Square contém variáveis e comportamento para a classe Shape e a classe
Square:
6643 $mySquare = new Square (10);
6644 print $mySquare> description () ///Uma forma com 4 lados
6645 print $mySquare> perímetro () //40
6646 print $mySquare> area () //100
6647 Seção 26.13: Classes Anônimas
6648 As classes anônimas foram introduzidas no PHP 7 para permitir que objetos rápidos e
únicos sejam facilmente criados Eles podem
6649 obtenha argumentos de construtor, estenda outras classes, implemente interfaces e
use características como as classes normais
6650 Em sua forma mais básica, uma classe anônima se parece com o seguinte:
6651 nova classe ("argumento do construtor") {
6652 função pública __construct ($param) {
6653 var_dump ($param);
6654 }
6655 }; //string (20) "argumento do construtor"
6656 Aninhar uma classe anônima dentro de outra classe não dá acesso a métodos privados
ou protegidos ou
6657 propriedades dessa classe externa O acesso a métodos protegidos e propriedades da
classe externa pode ser obtido por
6658 estendendo a classe externa da classe anônima O acesso a propriedades privadas da
classe externa pode ser obtido
6659 passandoos para o construtor da classe anônima
6660 Por exemplo:
6661 classe Outer {
6662 private $prop = 1;
6663 protegido $prop2 = 2;
6664 função protegida func1 () {
6665 return 3;
6666 }
6667 função pública func2 () {
6668 //passando pela propriedade $this> prop privada
6669 retornar nova classe ($this> prop) estende Outer {
6670 private $prop3;
6671 função pública __construct ($prop) {
6672 $this> prop3 = $prop;
6673 FF
6674 Notas PHP para Profissionais 161
6675 }
6676 função pública func3 () {
6677 //acessando a propriedade protegida Outer :: $prop2
6678 //acessando o método protegido Outer :: func1 ()
6679 //acessando a propriedade local self :: $prop3 que era privada de Outer :: $prop
6680 retorne $this> prop2 + $this> func1 () + $this> prop3;
6681 }
6682 };
6683 }
6684 }
6685 echo (new Outer) > func2 () > func3 (); //6
6686 FF
6687 Notas PHP para Profissionais 162
6688 Capítulo 27: Namespaces
6689 Seção 27.1: Declarando namespaces
6690 Uma declaração de namespace pode se parecer da seguinte maneira:
6691 namespace MyProject; Declarar o namespace MyProject
6692 namespace MyProject \ Security \ Cryptography; Declarar um namespace aninhado
6693 namespace MyProject {...} Declara um namespace com colchetes de fechamento
6694 É recomendável declarar apenas um único namespace por arquivo, mesmo que você possa
declarar quantos desejar
6695 um único arquivo:
6696 namespace primeiro {
6697 classe A { .}; //Defina a classe A no namespace Primeiro.
6698 }
6699 namespace Second {
6700 classe B {...}; //Defina a classe B no namespace Second.
6701 }
6702 namespace {
6703 classe C {...}; //Defina a classe C no namespace raiz.
6704 }
6705 Toda vez que você declara um namespace, as classes que você definir depois
pertencerão a esse namespace:
6706 namespace MyProject \ Shapes;
6707 retângulo de classe {...}
6708 class square {...}
6709 Círculo de turma {...}
6710 Uma declaração de namespace pode ser usada várias vezes em arquivos diferentes O
exemplo acima definiu três classes em
6711 o namespace MyProject \ Shapes em um único arquivo De preferência, isso seria
dividido em três arquivos, cada um começando
6712 com namespace MyProject \ Shapes ; Isso é explicado em mais detalhes no exemplo
padrão do PSR4.
6713 Seção 27.2: Referenciando uma classe ou função em um namespace
6714 Conforme mostrado em Declarando Namespaces, podemos definir uma classe em um
namespace da seguinte maneira:
6715 namespace MyProject \ Shapes;
6716 retângulo de classe {...}
6717 Para fazer referência a essa classe, o caminho completo (incluindo o namespace)
precisa ser usado:
6718 $retângulo = novo MyProject \ Shapes \ Rectangle ();
6719 Isto pode ser encurtado importando a classe através da declaração de uso:
6720 //Retângulo se torna um alias para MyProject \ Shapes \ Rectangle
6721 use MyProject \ Shapes \ Rectangle;
6722 $retângulo = novo retângulo ();
6723 FF
6724 Notas PHP para Profissionais 163
6725 Quanto ao PHP 7.0, você pode agrupar várias instruções de uso em uma única instrução
usando colchetes:
6726 use MyProject \ Shapes \ {
6727 Retângulo, //O mesmo que `use MyProject \ Shapes \ Rectangle
6728 Circle, //O mesmo que `use MyProject \ Shapes \ Circle`
6729 Triangle, //O mesmo que `use MyProject \ Shapes \ Triangle
6730 Polygon \ FiveSides, //Você também pode importar subnamespaces
6731 Polygon \ SixSides //Em uma instrução `use` agrupada
6732 };
6733 $retângulo = novo retângulo ();
6734 Às vezes, duas classes têm o mesmo nome Isso não é um problema se eles estiverem em
um namespace diferente, mas
6735 tornarse um problema ao tentar importálos com a declaração de uso:
6736 use MyProject \ Shapes \ Oval;
6737 use MyProject \ Languages \ Oval; //Aparentemente Oval também é uma língua!
6738 //Erro!
6739 Isso pode ser resolvido definindo um nome para o alias usando a palavrachave as:
6740 use MyProject \ Shapes \ Oval como OvalShape;
6741 use MyProject \ Languages \ Oval como OvalLanguage;
6742 Para fazer referência a uma classe fora do namespace atual, ele deve ser escapado
com um \, caso contrário, um namespace relativo
6743 caminho é assumido a partir do namespace atual:
6744 namespace MyProject \ Shapes;
6745 //Referencias MyProject \ Shapes \ Rectangle Corrigir!
6746 $a = novo retângulo ();
6747 //Referencias MyProject \ Shapes \ Rectangle Correto, mas desnecessário!
6748 $a = new \ MyProject \ Shapes \ Rectangle ();
6749 //Referencias MyProject \ Shapes \ MyProject \ Shapes \ Rectangle Incorreta!
6750 $a = novo MyProject \ Shapes \ Rectangle ();
6751 //Fazer referência a StdClass de dentro de um namespace requer um \ prefixo
6752 //já que não está definido em um namespace, significando que é global
6753 //Referências StdClass Corrigir!
6754 $a = new \ StdClass ();
6755 //Referencias MyProject \ Shapes \ StdClass Incorreta!
6756 $a = novo StdClass ();
6757 Seção 27.3: Declarando subnamespaces
6758 Para declarar um único namespace com hierarquia, use o seguinte exemplo:
6759 namespace MyProject \ Sub \ Level;
6760 const CONNECT_OK = 1;
6761 conexão de classe {/* .*/}
6762 FF
6763 Notas PHP para Profissionais 164
6764 função connect () {/* .*/}
6765 O exemplo acima cria:
6766 constante MyProject \ Sub \ Level \ CONNECT_OK
6767 classe MyProject \ Sub \ Level \ Connection e
6768 função MyProject \ Sub \ Level \ connect
6769 Seção 27.4: O que são namespaces?
6770 A comunidade PHP tem muitos desenvolvedores criando muito código Isso significa que
o código PHP de uma biblioteca pode usar
6771 o mesmo nome de classe que outra biblioteca Quando as duas bibliotecas são usadas no
mesmo namespace, elas colidem e
6772 causar problemas
6773 Namespaces resolvem esse problema Conforme descrito no manual de referência do PHP,
os namespaces podem ser comparados a
6774 diretórios do sistema operacional que possuem arquivos de namespace; dois arquivos
com o mesmo nome podem coexistir em
6775 diretórios Da mesma forma, duas classes PHP com o mesmo nome podem coexistir em
namespaces separados do PHP.
6776 É importante que você codifique seu código para que ele possa ser usado por outros
desenvolvedores sem medo de colidir
6777 com outras bibliotecas.
6778 FF
6779 Notas PHP para Profissionais 165
6780 Capítulo 28: Sessões
6781 Seção 28.1: session_start () Opções
6782 Começando com PHP Sessions, podemos passar um array com as opções do php.ini
baseadas em sessão para o session_start
6783 função
6784 Exemplo
6785 <?php
6786 if (version_compare (PHP_VERSION, '7.0.0')> = 0) {
6787 //php> = versão 7
6788 session_start ([
6789 'cache_limiter' => 'privado',
6790 'read_and_close' => true,
6791 ]);
6792 } outro {
6793 //versão do php <7
6794 session_start ();
6795 }
6796 ?>
6797 Este recurso também introduz uma nova configuração do php.ini chamada
session.lazy_write, que por padrão é true e significa
6798 esses dados da sessão só serão reescritos, se forem alterados
6799 Referenciação: https://wiki.php.net/rfc/sessionlockini
6800 Seção 28.2: Bloqueio de Sessão
6801 Como todos sabemos, o PHP grava os dados da sessão em um arquivo no lado do servidor
Quando uma solicitação é feita para o script php
6802 que inicia a sessão via session_start (), o PHP bloqueia esse arquivo de sessão,
resultando em bloquear /aguardar outras entradas
6803 pedidos para o mesmo session_id para completar, por causa do qual os outros pedidos
ficarão presos em session_start ()
6804 até ou a menos que o arquivo de sessão bloqueado não seja liberado
6805 O arquivo da sessão permanece bloqueado até que o script seja concluído ou a sessão
seja fechada manualmente Para evitar essa situação, ou seja
6806 para evitar que várias solicitações sejam bloqueadas, podemos iniciar a sessão e
fechar a sessão que liberará o bloqueio
6807 do arquivo de sessão e permitir continuar as solicitações restantes
6808 //php <7.0
6809 //iniciar sessão
6810 session_start ();
6811 //escreve dados para a sessão
6812 $_SESSION ['id'] = 123; //o arquivo da sessão está bloqueado, então outras
solicitações estão bloqueadas
6813 //fecha a sessão, libera o bloqueio
6814 session_write_close ();
6815 Agora, um vai pensar se a sessão está fechada como vamos ler os valores da sessão,
embelezar mesmo após a sessão ser fechada,
6816 sessão ainda está disponível Então, ainda podemos ler os dados da sessão.
6817 echo $_SESSION ['id']; //irá gerar 123
6818 Em php> = 7.0, podemos ter sessão read_only, sessão read_write e sessão lazy_write,
então pode não ser necessário
6819 usar session_write_close ()
6820 FF
6821 Notas PHP para Profissionais 166
6822 Seção 28.3: Manipulando dados da sessão
6823 A variável $_SESSION é uma matriz e você pode recuperála ou manipulála como uma
matriz normal
6824 <?php
6825 //Iniciando a sessão
6826 session_start ();
6827 //Armazenando o valor na sessão
6828 $_SESSION ['id'] = 342;
6829 //uso condicional de valores de sessão que podem ter sido definidos em uma sessão
anterior
6830 if (! isset ($_ SESSION ["login"])) {
6831 echo "Por favor, faça o login primeiro";
6832 Saída;
6833 }
6834 //agora você pode usar o login com segurança
6835 $user = $_SESSION ["login"];
6836 //Obtendo um valor dos dados da sessão ou com o valor padrão
6837 //usando o operador Null Coalescing no PHP 7
6838 $name = $_SESSION ['nome'] ?? 'Anônimo';
6839 Veja também Manipulando uma Matriz para mais referências sobre como trabalhar em uma
matriz
6840 Observe que, se você armazenar um objeto em uma sessão, ele poderá ser recuperado
com graça somente se você tiver um autoloader de classe ou
6841 você já carregou a classe Caso contrário, o objeto sairá como o tipo
__PHP_Incomplete_Class, que
6842 pode mais tarde levar a falhas Veja Espaço de nomes e Carregamento automático sobre
o carregamento automático.
6843 Aviso:
6844 Os dados da sessão podem ser seqüestrados Isso é descrito em: Segurança do PHP Pro:
dos Princípios de Segurança de Aplicativos ao
6845 Implementação da Defesa XSS Capítulo 7: Prevenindo o seqüestro de sessão Por isso,
pode ser altamente recomendável nunca
6846 guarde qualquer informação pessoal em $_SESSION Isso incluiria mais criticamente
números de cartão de crédito, governo
6847 IDs emitidos e senhas; mas também se estenderia a dados menos presumidos, como
nomes, emails, números de telefone,
6848 etc, que permitiria que um hacker personifique /comprometa um usuário legítimo Como
regra geral, use inútil /não pessoal
6849 valores, como identificadores numéricos, nos dados da sessão
6850 Seção 28.4: Destruir uma sessão inteira
6851 Se você tem uma sessão que você deseja destruir, você pode fazer isso com
session_destroy ()
6852 /*
6853 Vamos supor que nossa sessão seja assim:
6854 Array ([nome] => Jon, [id] => 123)
6855 Primeiro precisamos começar nossa sessão:
6856 */
6857 session_start ();
6858 /*
6859 Agora podemos remover todos os valores da superglobal `SESSION`:
6860 Se você omitiu este passo, todas as variáveis globais armazenadas no
6861 superglobal ainda existiria mesmo que a sessão tivesse sido destruída
6862 */
6863 $_SESSION = array ();
6864 //Se desejar eliminar a sessão, exclua também o cookie da sessão.
6865 FF
6866 Notas PHP para Profissionais 167
6867 //Nota: Isso destruirá a sessão e não apenas os dados da sessão!
6868 if (ini_get ("session.use_cookies")) {
6869 $params = session_get_cookie_params ();
6870 setcookie (session_name (), '', hora () 42000,
6871 $params ["caminho"], $params ["domínio"],
6872 $params ["secure"], $params ["httponly"]
6873 );
6874 }
6875 //Finalmente podemos destruir a sessão:
6876 session_destroy ();
6877 Usar session_destroy () é diferente de usar algo como $_SESSION = array (); que irá
remover todos os
6878 valores armazenados no SESSÃO superglobal, mas não destruirá a versão armazenada
real da sessão
6879 Nota: Usamos $_SESSION = array (); em vez de session_unset () porque o manual
estipula:
6880 Use session_unset () somente para códigos obsoletos mais antigos que não usem
$_SESSION
6881 Seção 28.5: Início da sessão segura sem erros
6882 Muitos desenvolvedores têm esse problema quando trabalham em grandes projetos,
especialmente se eles trabalham em alguns projetos modulares
6883 CMS em plugins, addons, componentes, etc Aqui está a solução para o início seguro da
sessão, onde a primeira versão verificada do PHP
6884 para cobrir todas as versões e no próximo é verificada se a sessão é iniciada Se a
sessão não existir, inicio a sessão com segurança E se
6885 sessão existe nada acontece
6886 if (version_compare (PHP_VERSION, '7.0.0')> = 0) {
6887 if (session_status () == PHP_SESSION_NONE) {
6888 session_start (array (
6889 'cache_limiter' => 'privado',
6890 'read_and_close' => true,
6891 ));
6892 }
6893 }
6894 else if (version_compare (PHP_VERSION, '5.4.0')> = 0)
6895 {
6896 if (session_status () == PHP_SESSION_NONE) {
6897 session_start ();
6898 }
6899 }
6900 outro
6901 {
6902 if (session_id () == '') {
6903 session_start ();
6904 }
6905 }
6906 Isso pode ajudálo muito a evitar o erro session_start
6907 Seção 28.6: Nome da Sessão
6908 Verificar se os cookies de sessão foram criados
6909 Nome da sessão é o nome do cookie usado para armazenar sessões Você pode usar isso
para detectar se os cookies de uma sessão
6910 foram criados para o usuário:
6911 FF
6912 Notas PHP para Profissionais 168
6913 if (isset ($_ COOKIE [session_name ()])) {
6914 session_start ();
6915 }
6916 Observe que esse método geralmente não é útil, a menos que você realmente não queira
criar cookies desnecessariamente
6917 Alterando o nome da sessão
6918 Você pode atualizar o nome da sessão chamando session_name ()
6919 //Definir o nome da sessão
6920 session_name ('novo nome');
6921 //Iniciar a sessão
6922 session_start ();
6923 Se nenhum argumento for fornecido em session_name (), o nome da sessão atual será
retornado
6924 Deve conter apenas caracteres alfanuméricos; deve ser curto e descritivo (ou seja,
para usuários com
6925 avisos de cookies ativados) O nome da sessão não pode conter apenas dígitos, pelo
menos uma letra deve ser
6926 presente Caso contrário, um novo ID de sessão é gerado a cada vez.
6927 FF
6928 Notas PHP para Profissionais 169
6929 Capítulo 29: Cookies
6930 detalhe do parâmetro
6931 nome O nome do cookie Esta é também a chave que você pode usar para recuperar o
valor do $_COOKIE super
6932 global Este é o único parâmetro obrigatório
6933 valor O valor para armazenar no cookie Esses dados são acessíveis ao navegador,
portanto, não armazene nada sensível
6934 Aqui
6935 expirar
6936 Um timestamp do Unix que representa quando o cookie deve expirar Se definido como
zero, o cookie expirará em
6937 o final da sessão Se configurado para um número menor que o timestamp atual do Unix,
o cookie expirará
6938 imediatamente
6939 caminho
6940 O escopo do cookie Se definido como /o cookie estará disponível em todo o domínio Se
definido como /somepath /
6941 então o cookie só estará disponível nesse caminho e descendentes desse caminho
Padrões para o
6942 caminho atual do arquivo em que o cookie está sendo configurado
6943 domínio
6944 O domínio ou subdomínio em que o cookie está disponível Se definido para o domínio
nu stackoverflow.com
6945 então o cookie estará disponível para esse domínio e todos os subdomínios Se
definido para um subdomínio
6946 meta.stackoverflow.com, em seguida, o cookie estará disponível apenas nesse
subdomínio e em todos os subdomínios
6947 secure Quando definido como TRUE, o cookie só será definido se existir uma conexão
HTTPS segura entre o cliente e
6948 o servidor
6949 httponly Especifica que o cookie só deve ser disponibilizado através do protocolo
HTTP /S e não deve
6950 estar disponível para linguagens de script do lado do cliente como JavaScript
Disponível apenas no PHP 5.2 ou posterior.
6951 Um cookie HTTP é um pequeno pedaço de dados enviado de um site e armazenado no
computador do usuário pela Web do usuário
6952 navegador enquanto o usuário está navegando
6953 Seção 29.1: Modificando um cookie
6954 O valor de um cookie pode ser modificado, redefinindo o cookie
6955 setcookie ("usuário", "John", tempo () + 86400, "/"); //assumindo que já existe um
cookie de "usuário"
6956 Cookies são parte do cabeçalho HTTP, então setcookie () deve ser chamado antes de
qualquer saída ser enviada para o
6957 navegador
6958 Ao modificar um cookie, certifiquese de que o caminho e os parâmetros de domínio de
setcookie () correspondam ao
6959 Um cookie existente ou um novo cookie será criado
6960 A parte do valor do cookie será automaticamente urlencoded quando você enviar o
cookie, e quando é
6961 recebido, ele é automaticamente decodificado e atribuído a uma variável com o mesmo
nome que o nome do cookie
6962 Seção 29.2: Configurando um Cookie
6963 Um cookie é definido usando a função setcookie () Como os cookies fazem parte do
cabeçalho HTTP, você deve definir os cookies
6964 antes de enviar qualquer saída para o navegador
6965 Exemplo:
6966 setcookie ("usuário", "Tom", tempo () + 86400, "/"); //verifica a sintaxe da função
params
6967 FF
6968 Notas PHP para Profissionais 170
6969 Descrição:
6970 Cria um cookie com o nome do usuário
6971 (Opcional) O valor do cookie é Tom
6972 (Opcional) Cookie expira em 1 dia (86400 segundos)
6973 (Opcional) Cookie está disponível em todo o site /
6974 (Opcional) O cookie é enviado apenas por HTTPS
6975 (Opcional) O cookie não está acessível para linguagens de script, como JavaScript
6976 Um cookie criado ou modificado só pode ser acessado em solicitações subsequentes
(onde caminho e domínio
6977 jogos) como o superglobal $_COOKIE não é preenchido com os novos dados imediatamente
6978 Seção 29.3: Verificando se um cookie está definido
6979 Use a função isset () na variável superglobal $_COOKIE para verificar se um cookie
está configurado
6980 Exemplo:
6981 //PHP <7.0
6982 if (isset ($_ COOKIE ['usuário'])) {
6983 //true, o cookie está definido
6984 echo 'Usuário é' $_COOKIE ['usuário'];
6985 outro {
6986 //false, cookie não está definido
6987 echo 'Usuário não está logado';
6988 }
6989 //PHP 7.0+
6990 echo 'Usuário é' $_COOKIE ['usuário'] ?? 'Usuário não está logado';
6991 Seção 29.4: Removendo um Cookie
6992 Para remover um cookie, defina o registro de data e hora de expiração para um
horário no passado Isso aciona o mecanismo de remoção do navegador:
6993 setcookie ('usuário', '', hora () 3600, '/');
6994 Ao excluir um cookie, verifique se os parâmetros path e domain de setcookie ()
correspondem ao cookie
6995 você está tentando excluir ou um novo cookie, que expira imediatamente, será criado
6996 Também é uma boa idéia desconfigurar o valor $_COOKIE no caso de a página atual
usálo:
6997 unset ($_ COOKIE ['usuário']);
6998 Seção 29.5: Recuperando um Cookie
6999 Recuperar e enviar um usuário com nome de cookie
7000 O valor de um cookie pode ser recuperado usando a variável global $_COOKIE exemplo,
se temos um cookie chamado usuário
7001 podemos recuperálo assim
7002 echo $_COOKIE ['usuário'];
7003 FF
7004 Notas PHP para Profissionais 171
7005 Capítulo 30: BuQering de saída
7006 Detalhes da Função
7007 ob_start () Inicia o buffer de saída, qualquer saída colocada depois disso será
capturada e não exibida
7008 ob_get_contents () Retorna todo o conteúdo capturado por ob_start ()
7009 ob_end_clean () Esvazia o buffer de saída e o desativa para o nível de aninhamento
atual
7010 ob_get_clean () Dispara ob_get_contents () e ob_end_clean ()
7011 ob_get_level () Retorna o nível de aninhamento atual do buffer de saída
7012 ob_flush () Limpe o buffer de conteúdo e envieo para o navegador sem terminar o
buffer
7013 ob_implicit_flush () Permite o fluxo implícito após cada chamada de saída
7014 ob_end_flush () Limpe o buffer de conteúdo e envieo para o navegador, finalizando
também o buffer
7015 Seção 30.1: Uso básico obtendo conteúdo entre bu.ers
7016 e limpando
7017 O buffer de saída permite armazenar qualquer conteúdo textual (texto, HTML) em uma
variável e enviálo ao navegador como um
7018 peça no final do seu roteiro Por padrão, o php envia seu conteúdo como ele o
interpreta.
7019 <?php
7020 //Ativar o buffer de saída
7021 ob_start ();
7022 //Imprime alguma saída para o buffer (via php)
7023 imprimir 'Olá';
7024 //Você também pode 'sair' do PHP
7025 ?>
7026 <em> mundo </em>
7027 <?php
7028 //Retorna o buffer E limpa
7029 $content = ob_get_clean ();
7030 //Retorna nosso buffer e depois limpa
7031 # $content = ob_get_contents ();
7032 # $did_clear_buffer = ob_end_clean ();
7033 imprimir ($content);
7034 #> "Hello <em> World </em>"
7035 Qualquer conteúdo produzido entre ob_start () e ob_get_clean () será capturado e
colocado na variável
7036 $content
7037 Chamar ob_get_clean () aciona tanto ob_get_contents () quanto ob_end_clean ()
7038 Seção 30.2: Processando o buffer via um retorno de chamada
7039 Você pode aplicar qualquer tipo de processamento adicional à saída passando um
callable para ob_start ()
7040 <?php
7041 função clearAllWhiteSpace ($buffer) {
7042 return str_replace (array ("\ n", "\ t", ''), '', $buffer);
7043 }
7044 FF
7045 Notas PHP para Profissionais 172
7046 ob_start ('clearAllWhiteSpace');
7047 ?>
7048 <h1> Lorem Ipsum </h1>
7049 <p> <strong> Pellentesque habitante morbi tristique </strong> senectus e netus et
machuada fames ac
7050 turpis egestas <a href="#"> Donec non enim </a> em turpis pulvinar facilisis </p>
7051 <h2> Cabeçalho Nível 2 </h2>
7052 <ol>
7053 <li> Lorem ipsum dolor sentese, consectetuer adipiscing elit </li>
7054 <li> Aliquam tincidunt mauris eu risus </li>
7055 </ol>
7056 <?php
7057 /* A saída será liberada e processada quando o script terminar ou chamar
7058 ob_end_flush ();
7059 */
7060 Saída:
7061 <h1> LoremIpsum </h1> <p> <strong> Pellentesquehabitantmorbitristique </strong>
senectusetnetusetmalesuada
7062 famesacturpisegestas <ahref = "#"> Donecnonenim </a> inturpispulvinarfacilisis </p>
<h2> HeaderLevel2 </h2>
7063 <ol> <li> Loremipsumdolorsitamet, consectetueradipiscingelit </li> <li>
Aliquamtinciduntmauriseurisus </
7064 li> </ol>
7065 Seção 30.3: Buffer de saída aninhada
7066 Você pode aninhar buffers de saída e buscar o nível para que eles forneçam conteúdo
diferente usando o ob_get_level ()
7067 função
7068 <?php
7069 $i = 1;
7070 $output = null;
7071 while ($i <= 5) {
7072 //Cada loop, cria um novo nível de buffer de saída
7073 ob_start ();
7074 print "Nível do ninho atual:" ob_get_level () "\ n";
7075 $i ++;
7076 }
7077 //Estamos no nível 5 agora
7078 print 'Terminou no nível:' ob_get_level () PHP_EOL;
7079 //Get clean will `pop` o conteúdo do nível mais alto (5)
7080 $output = ob_get_clean ();
7081 imprima $output;
7082 print 'Popped level 5, então agora começamos a partir de 4' PHP_EOL;
7083 //Estamos agora no nível 4 (aparecemos 5 acima)
7084 //Para cada nível subimos, voltamos e pegamos o buffer
7085 while ($i> 2) {
7086 print "Nível do ninho atual:" ob_get_level () "\ n";
7087 echo ob_get_clean ();
7088 $i;
7089 FF
7090 Notas PHP para Profissionais 173
7091 }
7092 Saídas:
7093 Nível de ninho atual: 1
7094 Nível de ninho atual: 2
7095 Nível de ninho atual: 3
7096 Nível de ninho atual: 4
7097 Nível de ninho atual: 5
7098 Terminou no nível: 5
7099 Popped level 5, então agora começamos a partir de 4
7100 Nível de ninho atual: 4
7101 Nível de ninho atual: 3
7102 Nível de ninho atual: 2
7103 Nível de ninho atual: 1
7104 Seção 30.4: Executando o bufer de saída antes de qualquer conteúdo
7105 ob_start ();
7106 $user_count = 0;
7107 foreach ($users as $user) {
7108 if ($user ['acesso']! = 7) {continuar; }
7109 ?>
7110 <li class = "usuários usuário <?phpecho $user ['id'];?>">
7111 <a href="<?php echo $user['link']; ?> ">
7112 <?phpecho $user ['name']?>
7113 </a>
7114 </li>
7115 <?php
7116 $user_count ++;
7117 }
7118 $users_html = ob_get_clean ();
7119 if (! $user_count) {
7120 cabeçalho ('Localização: /404.php');
7121 Saída();
7122 }
7123 ?>
7124 <html>
7125 <cabeça>
7126 <title> Resultados do usuário do nível 7 (<?phpecho $user_count;?>) </title>
7127 </head>
7128 <body>
7129 <h2> Temos um total de <?phpecho $user_count; ?> usuários com nível de acesso 7 </h2>
7130 <ul class = "lista de usuários">
7131 <?phpecho $users_html; ?>
7132 </ul>
7133 </body>
7134 </html>
7135 Neste exemplo, assumimos que $users é um array multidimensional, e passamos por ele
para encontrar todos os usuários com um
7136 nível de acesso de 7
7137 Se não houver resultados, redirecionamos para uma página de erro
7138 Estamos usando o buffer de saída aqui porque estamos acionando um redirecionamento
header () baseado no resultado do loop
7139 FF
7140 Notas PHP para Profissionais 174
7141 Seção 30.5: saída de fluxo para o cliente
7142 /**
7143 * Permite o streaming do buffer de saída Chamando esta função
7144 * imediatamente libera o buffer para o cliente, e qualquer
7145 * saída subseqüente será enviada diretamente para o cliente
7146 */
7147 função _stream () {
7148 ob_implicit_flush (true);
7149 ob_end_flush ();
7150 }
7151 Seção 30.6: Usando o Buffer de Saída para armazenar o conteúdo em um arquivo,
7152 útil para relatórios, faturas, etc
7153 <?php
7154 ob_start ();
7155 ?>
7156 <html>
7157 <cabeça>
7158 <title> Exemplo de fatura </title>
7159 </head>
7160 <body>
7161 <h1> Fatura # 0000 </h1>
7162 <h2> Custo: & libra; 15.000 </h2>
7163 .
7164 </body>
7165 </html>
7166 <?php
7167 $html = ob_get_clean ();
7168 $handle = fopen ('invoices /exampleinvoice.html', 'w');
7169 fwrite ($handle, $html);
7170 fclose ($handle);
7171 Este exemplo pega o documento completo e o grava no arquivo, ele não exibe o
documento no navegador,
7172 mas faça usando echo $html;
7173 Seção 30.7: Uso típico e motivos para usar ob_start
7174 O ob_start é especialmente útil quando você tem redirecionamentos em sua página Por
exemplo, o código a seguir não funcionará:
7175 Olá!
7176 <?php
7177 cabeçalho ("Localização: somepage.php");
7178 ?>
7179 O erro que será dado é algo como: cabeçalhos já enviados por <xxx> na linha <xxx>
7180 Para corrigir esse problema, você escreveria algo assim no início de sua página:
7181 <?php
7182 ob_start ();
7183 ?>
7184 E algo assim no final da sua página:
7185 FF
7186 Notas PHP para Profissionais 175
7187 <?php
7188 ob_end_flush ();
7189 ?>
7190 Isso armazena todo o conteúdo gerado em um buffer de saída e o exibe de uma só vez
Portanto, se você tiver algum redirecionamento
7191 solicita sua página, que será acionada antes que qualquer dado seja enviado,
eliminando a possibilidade de um cabeçalho já ter sido enviado
7192 erro ocorrendo
7193 Seção 30.8: Capturando o buffer de saída para reutilizar mais tarde
7194 Neste exemplo, temos uma matriz contendo alguns dados
7195 Nós capturamos o buffer de saída em $items_li_html e o usamos duas vezes na página
7196 <?php
7197 //Comece a capturar a saída
7198 ob_start ();
7199 $items = ['Home', 'Blog', 'FAQ', 'Contato'];
7200 foreach ($itens como $item):
7201 //Note que estamos prestes a sair "do PHP terra"
7202 ?>
7203 <li> <?phpecho $item?> </li>
7204 <?php
7205 //De volta à terra do PHP
7206 endforeach;
7207 //$items_lists contém todo o HTML capturado pelo buffer de saída
7208 $items_li_html = ob_get_clean ();
7209 ?>
7210 <! Menu 1: Agora podemos reutilizálo (várias vezes, se necessário) em nosso HTML >
7211 <ul class = "headernav">
7212 <?phpecho $items_li_html?>
7213 </ul>
7214 <! Menu 2 >
7215 <ul class = "rodapénav">
7216 <?phpecho $items_li_html?>
7217 </ul>
7218 Salve o código acima em um arquivo output_buffer.php e executeo via php
output_buffer.php
7219 Você deve ver os 2 itens da lista que criamos acima com os mesmos itens da lista que
geramos no PHP usando a saída
7220 amortecedor:
7221 <! Menu 1: Agora podemos reutilizálo (várias vezes, se necessário) em nosso HTML >
7222 <ul class = "headernav">
7223 <li> Início </li>
7224 <li> Blog </li>
7225 <li> FAQ </li>
7226 <li> Contato </li>
7227 </ul>
7228 <! Menu 2 >
7229 <ul class = "rodapénav">
7230 FF
7231 Notas PHP para Profissionais 176
7232 <li> Início </li>
7233 <li> Blog </li>
7234 <li> FAQ </li>
7235 <li> Contato </li>
7236 </ul>
7237 FF
7238 Notas PHP para Profissionais 177
7239 Capítulo 31: JSON
7240 Detalhes do Parâmetro
7241 json_encode
7242 valor O valor que está sendo codificado Pode ser qualquer tipo, exceto um recurso
Todos os dados da string devem ser codificados em UTF8.
7243 opções
7244 Máscara de bits que consiste em JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP,
JSON_HEX_APOS,
7245 JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT,
7246 JSON_PRESERVE_ZERO_FRACTION, JSON_UNESCAPED_UNICODE, JSON_PARTIAL_OUTPUT_ON_ERROR
7247 O comportamento dessas constantes é descrito na página de constantes JSON
7248 profundidade Defina a profundidade máxima Deve ser maior que zero.
7249 json_decode
7250 json A string json sendo decodificada Esta função só funciona com strings
codificadas em UTF8.
7251 assoc Deve funcionar retornar array associativo em vez de objetos
7252 opções Bitmask de opções de decodificação JSON Atualmente, apenas
JSON_BIGINT_AS_STRING é suportado (o padrão é
7253 elenco grandes inteiros como flutuadores)
7254 JSON (JavaScript Object Notation) é uma maneira independente de plataforma e
linguagem de serializar objetos em texto simples
7255 Como é frequentemente usado na Web e, portanto, é PHP, existe uma extensão básica
para trabalhar com JSON no PHP
7256 Seção 31.1: decodificando uma string JSON
7257 A função json_decode () pega uma string codificada JSON como seu primeiro parâmetro
e a analisa em uma variável PHP
7258 Normalmente, json_decode () retornará um objeto de \ stdClass se o item de nível
superior no objeto JSON for um dicionário ou
7259 uma matriz indexada se o objeto JSON for uma matriz Ele também retornará valores
escalares ou NULL para certos valores escalares,
7260 como strings simples, "true", "false" e "null" Também retorna NULL em qualquer erro.
7261 //Retorna um objeto (o item de nível superior na string JSON é um dicionário JSON)
7262 $json_string = '{"nome": "Jeff", "idade": 20, "ativo": verdadeiro, "cores":
["vermelho", "azul"]}';
7263 $object = json_decode ($json_string);
7264 printf ('Olá% s, Você tem% s anos de idade.', $object> nome, $objeto> idade);
7265 Olá, Jeff, você tem 20 anos
7266 //Retorna uma matriz (o item de nível superior na string JSON é uma matriz JSON)
7267 $json_string = '["Jeff", 20, verdadeiro, ["vermelho", "azul"]]';
7268 $array = json_decode ($json_string);
7269 printf ('Olá% s, Você tem% s anos de idade.', $array [0], $array [1]);
7270 Use var_dump () para visualizar os tipos e valores de cada propriedade no objeto que
nós decodificamos acima
7271 //Descarrega nosso objeto $acima para ver como foi decodificado
7272 var_dump (objeto $);
7273 Saída (observe os tipos de variáveis):
7274 class stdClass # 2 (4) {
7275 ["nome"] => string (4) "Jeff"
7276 ["idade"] => int (20)
7277 ["ativo"] => bool (verdadeiro)
7278 ["cores"] =>
7279 array (2) {
7280 [0] => string (3) "vermelho"
7281 [1] => string (4) "azul"
7282 }
7283 FF
7284 Notas PHP para Profissionais 178
7285 }
7286 Nota: Os tipos de variáveis no JSON foram convertidos em seu equivalente ao PHP
7287 Para retornar uma matriz associativa para objetos JSON em vez de retornar um objeto,
passe true como o segundo parâmetro
7288 para json_decode ()
7289 $json_string = '{"nome": "Jeff", "idade": 20, "ativo": verdadeiro, "cores":
["vermelho", "azul"]}';
7290 $array = json_decode ($json_string, true); //Observe o segundo parâmetro
7291 var_dump ($array);
7292 Saída (observe a estrutura associativa da matriz):
7293 array (4) {
7294 ["nome"] => string (4) "Jeff"
7295 ["idade"] => int (20)
7296 ["ativo"] => bool (verdadeiro)
7297 ["cores"] =>
7298 array (2) {
7299 [0] => string (3) "vermelho"
7300 [1] => string (4) "azul"
7301 }
7302 }
7303 O segundo parâmetro ($assoc) não tem efeito se a variável a ser retornada não for um
objeto
7304 Nota: Se você usar o parâmetro $assoc, perderá a distinção entre uma matriz vazia e
um objeto vazio
7305 Isso significa que executar o json_encode () na saída decodificada novamente
resultará em uma estrutura JSON diferente
7306 Se a string JSON tiver uma "profundidade", mais de 512 elementos (20 elementos nas
versões anteriores a 5.2.3 ou 128 na versão
7307 5.2.3) em recursão, a função json_decode () retorna NULL Nas versões 5.3 ou
posteriores, esse limite pode ser controlado
7308 usando o terceiro parâmetro ($depth), como discutido abaixo
7309 De acordo com o manual:
7310 PHP implementa um superconjunto de JSON conforme especificado no RFC 4627 original
ele também codifica e
7311 decodificar tipos escalares e NULL RFC 4627 suporta apenas esses valores quando eles
são aninhados dentro de uma matriz
7312 ou um objeto Embora este superconjunto seja consistente com a definição expandida de
"texto JSON" no mais recente
7313 »RFC 7159 (que tem como objetivo substituir a RFC 4627) e» ECMA404, isso pode causar
problemas de interoperabilidade
7314 com analisadores JSON mais antigos que aderem estritamente ao RFC 4627 ao codificar
um único valor escalar
7315 Isso significa que, por exemplo, uma string simples será considerada um objeto JSON
válido no PHP:
7316 $json = json_decode ('"alguma string"', true);
7317 var_dump ($json, json_last_error_msg ());
7318 Saída:
7319 string (11) "alguma string"
7320 string (8) "Nenhum erro"
7321 Mas strings simples, não em uma matriz ou objeto, não fazem parte do padrão RFC 4627
Como resultado, tais verificadores online
7322 como JSLint, JSON Formatter & Validator (no modo RFC 4627), você receberá um erro.
7323 FF
7324 Notas PHP para Profissionais 179
7325 Existe um terceiro parâmetro $depth para a profundidade da recursão (o valor padrão
é 512), o que significa a quantidade de
7326 objetos aninhados dentro do objeto original a ser decodificado
7327 Existe um quarto parâmetro $options Atualmente, aceita apenas um valor,
JSON_BIGINT_AS_STRING O padrão
7328 O comportamento (que deixa esta opção) é converter inteiros grandes em floats em vez
de strings
7329 Variantes nãominúsculas inválidas dos literais verdadeiro, falso e nulo não são mais
aceitas como entrada válida
7330 Então, este exemplo:
7331 var_dump (json_decode ('tRue'), json_last_error_msg ());
7332 var_dump (json_decode ('tRUe'), json_last_error_msg ());
7333 var_dump (json_decode ('tRUE'), json_last_error_msg ());
7334 var_dump (json_decode ('TRUe'), json_last_error_msg ());
7335 var_dump (json_decode ('TRUE'), json_last_error_msg ());
7336 var_dump (json_decode ('true'), json_last_error_msg ());
7337 Antes do PHP 5.6:
7338 bool (verdadeiro)
7339 string (8) "Nenhum erro"
7340 bool (verdadeiro)
7341 string (8) "Nenhum erro"
7342 bool (verdadeiro)
7343 string (8) "Nenhum erro"
7344 bool (verdadeiro)
7345 string (8) "Nenhum erro"
7346 bool (verdadeiro)
7347 string (8) "Nenhum erro"
7348 bool (verdadeiro)
7349 string (8) "Nenhum erro"
7350 E depois:
7351 NULO
7352 string (12) "Erro de sintaxe"
7353 NULO
7354 string (12) "Erro de sintaxe"
7355 NULO
7356 string (12) "Erro de sintaxe"
7357 NULO
7358 string (12) "Erro de sintaxe"
7359 NULO
7360 string (12) "Erro de sintaxe"
7361 bool (verdadeiro)
7362 string (8) "Nenhum erro"
7363 Comportamento semelhante ocorre para falso e nulo
7364 Note que json_decode () retornará NULL se a string não puder ser convertida
7365 $json = "{'nome': 'Jeff', 'idade': 20}"; //json inválido
7366 $person = json_decode ($json);
7367 echo $person> name; //Aviso: Tentativa de obter propriedade de não objeto: retorna
nulo
7368 echo json_last_error ();
7369 # 4 (JSON_ERROR_SYNTAX)
7370 FF
7371 Notas PHP para Profissionais 180
7372 echo json_last_error_msg ();
7373 # caráter inesperado
7374 Não é seguro confiar apenas no valor de retorno NULL para detectar erros Por
exemplo, se a cadeia JSON contiver
7375 nada além de "null", json_decode () retornará null, mesmo que nenhum erro tenha
ocorrido
7376 Seção 31.2: codificando uma string JSON
7377 A função json_encode irá converter um array PHP (ou, desde o PHP 5.4, um objeto que
implementa o
7378 Interface JsonSerializable) para uma string codificada em JSON Ele retorna uma
string codificada JSON em sucesso ou FALSE em
7379 falha
7380 $array = [
7381 'name' => 'Jeff',
7382 'idade' => 20,
7383 'active' => true,
7384 'colors' => ['red', 'blue'],
7385 'values' => [0 => 'foo', 3 => 'bar'],
7386 ];
7387 Durante a codificação, os tipos de dados PHP string, integer e boolean são
convertidos em seu equivalente JSON
7388 Matrizes associativas são codificadas como objetos JSON e quando chamadas com
argumentos padrão as matrizes indexadas são
7389 codificado como matrizes JSON (A menos que as chaves do array não sejam uma
sequência numérica contínua a partir de 0, em que
7390 caso a matriz será codificada como um objeto JSON.)
7391 echo json_encode ($array);
7392 Saída:
7393 {"nome": "Jeff", "idade": 20, "ativo": verdadeiro, "cores": ["vermelho", "azul"],
"valores": {"0": "foo", "3 ":"Barra"}}
7394 Argumentos
7395 Desde o PHP 5.3, o segundo argumento para json_encode é um bitmask que pode ser um
ou mais dos seguintes
7396 Como acontece com qualquer bitmask, eles podem ser combinados com o operador binário
OR |
7397 Versão do PHP 5.x = 5.3
7398 JSON_FORCE_OBJECT
7399 Força a criação de um objeto em vez de um array
7400 $array = ['Joel', 23, verdadeiro, ['vermelho', 'azul']];
7401 echo json_encode ($array);
7402 echo json_encode ($array, JSON_FORCE_OBJECT);
7403 Saída:
7404 ["Joel", 23, verdadeiro, ["vermelho", "azul"]]
7405 {"0": "Joel", "1": 23, "2": verdadeiro, "3": {"0": "vermelho", "1": "azul"}}
7406 JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_HEX_QUOT
7407 Garante as seguintes conversões durante a codificação:
7408 FF
7409 Notas PHP para Profissionais 181
7410 Saída de entrada constante
7411 JSON_HEX_TAG <\ u003C
7412 JSON_HEX_TAG> \ u003E
7413 JSON_HEX_AMP & \ u0026
7414 JSON_HEX_APOS '\ u0027
7415 JSON_HEX_QUOT "\ u0022
7416 $array = ["tag" => "<>", "amp" => "&", "apos" => "'", "quot" => "\" "];
7417 echo json_encode ($array);
7418 echo json_encode ($array, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS |
JSON_HEX_QUOT);
7419 Saída:
7420 {"tag": "<>", "amp": "&", "apos": "'", "quot": "\" "}
7421 {"tag": "\ u003C \ u003E", "amp": "\ u0026", "apos": "\ u0027", "quot": "\ u0022"}
7422 Versão do PHP 5.x = 5.3
7423 JSON_NUMERIC_CHECK
7424 Garante que as cadeias numéricas sejam convertidas em números inteiros
7425 $array = ['23452', 23452];
7426 echo json_encode ($array);
7427 echo json_encode ($array, JSON_NUMERIC_CHECK);
7428 Saída:
7429 ["23452", 23452]
7430 [23452,23452]
7431 Versão do PHP 5.x = 5.4
7432 JSON_PRETTY_PRINT
7433 Torna o JSON facilmente legível
7434 $array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
7435 echo json_encode ($array);
7436 echo json_encode ($array, JSON_PRETTY_PRINT);
7437 Saída:
7438 {"a": 1, "b": 2, "c": 3, "d": 4}
7439 {
7440 "a": 1,
7441 "b": 2,
7442 "c": 3,
7443 "d": 4
7444 }
7445 JSON_UNESCAPED_SLASHES
7446 Inclui barras sem escape /encaminhadas na saída
7447 $array = ['nome do arquivo' => 'exemplo.txt', 'caminho' => '/completo /caminho /para
/arquivo /'];
7448 echo json_encode ($array);
7449 echo json_encode ($array, JSON_UNESCAPED_SLASHES);
7450 Saída:
7451 FF
7452 Notas PHP para Profissionais 182
7453 {"nome do arquivo": "exemplo.txt", "caminho": "\ /completo \ /caminho \ /para \
/arquivo"}
7454 {"nomedoarquivo": "exemplo.txt", "caminho": "/completo /caminho /para /arquivo"}
7455 JSON_UNESCAPED_UNICODE
7456 Inclui caracteres codificados em UTF8 na saída, em vez de strings codificadas por \ u
7457 $blues = ["english" => "azul", "norueguês" => "bl ‫"ו‬, "alemão" => "blau"];
7458 echo json_encode ($blues);
7459 echo json_encode ($blues, JSON_UNESCAPED_UNICODE);
7460 Saída:
7461 {"english": "azul", "norueguês": "bl \ u00e5", "alemão": "blau"}
7462 {"english": "azul", "norueguês": "bl ‫"ו‬, "alemão": "blau"}
7463 Versão do PHP 5.x = 5.5
7464 JSON_PARTIAL_OUTPUT_ON_ERROR
7465 Permite que a codificação continue se alguns valores não codificáveis forem
encontrados
7466 $fp = fopen ("foo.txt", "r");
7467 $array = ["arquivo" => $fp, "nome" => "foo.txt"];
7468 echo json_encode ($array); //sem saída
7469 echo json_encode ($array, JSON_PARTIAL_OUTPUT_ON_ERROR);
7470 Saída:
7471 {"file": null, "name": "foo.txt"}
7472 Versão do PHP 5.x = 5.6
7473 JSON_PRESERVE_ZERO_FRACTION
7474 Garante que os carros alegóricos são sempre codificados como flutuadores
7475 $array = [5,0, 5,5];
7476 echo json_encode ($array);
7477 echo json_encode ($array, JSON_PRESERVE_ZERO_FRACTION);
7478 Saída:
7479 [5,5,5]
7480 [5,0,5,5]
7481 Versão do PHP 7.x = 7.1
7482 JSON_UNESCAPED_LINE_TERMINATORS
7483 Quando usado com JSON_UNESCAPED_UNICODE, reverte para o comportamento de versões
mais antigas do PHP e não
7484 caracteres U + 2028 SEPARADOR DE LINHA e U + 2029 PARÁGRAFO SEPARADOR Embora válido
em JSON, esses caracteres
7485 não são válidos em JavaScript, portanto, o comportamento padrão de
JSON_UNESCAPED_UNICODE foi alterado na versão 7.1
7486 $array = ["linha" => "\ xe2 \ x80 \ xa8", "parágrafo" => "\ xe2 \ x80 \ xa9"];
7487 echo json_encode ($array, JSON_UNESCAPED_UNICODE);
7488 echo json_encode ($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);
7489 Saída:
7490 {"line": "\ u2028", "paragraph": "\ u2029"}
7491 FF
7492 Notas PHP para Profissionais 183
7493 {"line": "", "paragraph": ""}
7494 Seção 31.3: Depurando erros JSON
7495 Quando json_encode ou json_decode não consegue analisar a string fornecida, ela
retornará false O próprio PHP não aumentará
7496 quaisquer erros ou avisos quando isso acontece, o ônus está no usuário para usar o
json_last_error () e
7497 json_last_error_msg () funções para verificar se ocorreu um erro e agir de acordo
com sua aplicação (depuração, show
7498 uma mensagem de erro, etc.)
7499 O exemplo a seguir mostra um erro comum ao trabalhar com JSON, uma falha na
decodificação /codificação de uma cadeia JSON
7500 (devido à passagem de uma string codificada UTF8 incorreta, por exemplo)
7501 //Uma string JSON formada incorretamente
7502 $jsonString = json_encode ("{'JSON ruim: \ xB1 \ x31}");
7503 if (json_last_error ()! = JSON_ERROR_NONE) {
7504 printf ("JSON Error:% s", json_last_error_msg ());
7505 }
7506 #> JSON Erro: caracteres UTF8 malformados, possivelmente codificados incorretamente
7507 json_last_error_msg
7508 json_last_error_msg () retorna uma mensagem legível do último erro que ocorreu ao
tentar
7509 codificar /decodificar uma string
7510 Esta função sempre retornará uma string, mesmo que nenhum erro tenha ocorrido
7511 A string padrão sem erro é Sem Erro
7512 Ele retornará false se algum outro erro (desconhecido) ocorreu
7513 Cuidado ao usar isso em loops, pois o json_last_error_msg será substituído em cada
iteração
7514 Você só deve usar essa função para obter a mensagem para exibição, e não para testar
nas instruções de controle
7515 //Não faça isso:
7516 if (json_last_error_msg ()) {} //sempre verdadeiro (é uma string)
7517 if (json_last_error_msg ()! = "Sem erro") {} //Má prática
7518 //Faça isto: (teste o inteiro contra uma das constantes prédefinidas)
7519 if (json_last_error ()! = JSON_ERROR_NONE) {
7520 //Use json_last_error_msg para exibir somente a mensagem, (não teste contra ela)
7521 printf ("JSON Error:% s", json_last_error_msg ());
7522 }
7523 Esta função não existe antes do PHP 5.5 Aqui está uma implementação de polyfill:
7524 if (! function_exists ('json_last_error_msg')) {
7525 função json_last_error_msg () {
7526 static $ERRORS = array (
7527 JSON_ERROR_NONE => 'Sem erro',
7528 JSON_ERROR_DEPTH => 'Profundidade máxima da pilha excedida',
7529 JSON_ERROR_STATE_MISMATCH => 'Incompatibilidade de estado (JSON inválido ou
malformado)',
7530 JSON_ERROR_CTRL_CHAR => 'Controlar erro de caractere, possivelmente codificado
incorretamente',
7531 JSON_ERROR_SYNTAX => 'Erro de sintaxe',
7532 JSON_ERROR_UTF8 => 'Caracteres UTF8 malformados, possivelmente codificados
incorretamente'
7533 );
7534 $error = json_last_error ();
7535 FF
7536 Notas PHP para Profissionais 184
7537 retornar isset ($ERRORS [$error])? $ERRORS [$error]: 'Erro desconhecido';
7538 }
7539 }
7540 json_last_error
7541 json_last_error () retorna um inteiro mapeado para uma das constantes prédefinidas
fornecidas pelo PHP
7542 Significado Constante
7543 JSON_ERROR_NONE Nenhum erro ocorreu
7544 JSON_ERROR_DEPTH A profundidade máxima da pilha foi excedida
7545 JSON_ERROR_STATE_MISMATCH JSON inválido ou malformado
7546 JSON_ERROR_CTRL_CHAR Erro de caractere de controle, possivelmente codificado
incorretamente
7547 JSON_ERROR_SYNTAX Erro de sintaxe (desde o PHP 5.3.3)
7548 JSON_ERROR_UTF8 Caracteres UTF8 malformados, possivelmente codificados
incorretamente (desde o PHP 5.5.0)
7549 JSON_ERROR_RECURSION Uma ou mais referências recursivas no valor a ser codificado
7550 JSON_ERROR_INF_OR_NAN Um ou mais valores NAN ou INF no valor a ser codificado
7551 JSON_ERROR_UNSUPPORTED_TYPE Um valor de um tipo que não pode ser codificado foi
fornecido
7552 Seção 31.4: Usando o JsonSerializable em um objeto
7553 Versão do PHP 5.x = 5.4
7554 Quando você cria APIs REST, pode ser necessário reduzir as informações de um objeto
a ser passado para o cliente
7555 aplicação Para esse propósito, este exemplo ilustra como usar a interface
JsonSerialiazble.
7556 Neste exemplo, a classe User na verdade estende um objeto de modelo de banco de
dados de um ORM hipotético
7557 classe User extends Model implementa JsonSerializable {
7558 $id público;
7559 nome $público;
7560 public $sobrenome;
7561 $username público;
7562 $password pública;
7563 $email público;
7564 public $date_created;
7565 public $date_edit;
7566 public $role;
7567 status $público;
7568 Função pública jsonSerialize () {
7569 Retorna [
7570 'name' => $this> nome,
7571 'sobrenome' => $this> sobrenome,
7572 'username' => $this> nome de usuário
7573 ];
7574 }
7575 }
7576 Adicione a implementação de JsonSerializable à classe, fornecendo o método
jsonSerialize ()
7577 Função pública jsonSerialize ()
7578 Agora, no seu controlador de aplicativo ou script, ao passar o objeto Usuário para
json_encode (), você obterá o retorno
7579 json codificado array do método jsonSerialize () em vez do objeto inteiro.
7580 FF
7581 Notas PHP para Profissionais 185
7582 json_encode ($User);
7583 Retornará:
7584 {"name": "John", "sobrenome": "Doe", "username": "TestJson"}
7585 propriedades valores exemplo
7586 Isso reduzirá a quantidade de dados retornados de um terminal REST e permitirá
excluir propriedades do objeto
7587 de uma representação json
7588 Usando propriedades particulares e protegidas com json_encode ()
7589 Para evitar o uso de JsonSerializable, também é possível usar propriedades privadas
ou protegidas para ocultar informações de classe
7590 da saída json_encode () A classe, então, não precisa implementar \ JsonSerializable.
7591 A função json_encode () codificará apenas as propriedades públicas de uma classe em
JSON
7592 <?php
7593 class User {
7594 //propriedades privadas somente dentro desta classe
7595 $ID privado;
7596 private $date_created;
7597 private $date_edit;
7598 //propriedades usadas em classes estendidas
7599 senha $protegida;
7600 $email protegido;
7601 função $protegida;
7602 status $protegido;
7603 //compartilha essas propriedades com o usuário final
7604 nome $público;
7605 public $sobrenome;
7606 $username público;
7607 //jsonSerialize () não é necessário aqui
7608 }
7609 $theUser = new Usuário ();
7610 var_dump (json_encode ($theUser));
7611 Saída:
7612 string (44) "{" nome ": nulo," sobrenome ": null," nome de usuário ": nulo}"
7613 Seção 31.5: cabeçalho json e a resposta retornada
7614 Adicionando um cabeçalho com o tipo de conteúdo como JSON:
7615 <?php
7616 $result = array ('menu1' => 'home', 'menu2' => 'código php', 'menu3' => 'sobre');
7617 FF
7618 PHP Notes for Professionals 186
7619 //retorna a resposta do json:
7620 cabeçalho ('ContentType: application /json'); //< declaração de cabeçalho
7621 echo json_encode (resultado $, true); //< codificar
7622 Saída();
7623 O cabeçalho está lá para que seu aplicativo possa detectar quais dados foram
retornados e como devem ser tratados
7624 Observe que: o cabeçalho do conteúdo é apenas uma informação sobre o tipo de dados
retornados
7625 Se você estiver usando o UTF8, você pode usar:
7626 header ("Tipo de Conteúdo: application /json; charset = utf8");
7627 Exemplo de jQuery:
7628 $.ajax ({
7629 url: 'url_your_page_php_that_return_json'
7630 }) done (function (data) {
7631 console.table ('json', data);
7632 console.log ('Menu1:', data.menu1);
7633 });
7634 FF
7635 Notas PHP para Profissionais 187
7636 Capítulo 32: Cliente SOAP
7637 Detalhes do Parâmetro
7638 $wsdl URI de WSDL ou NULL se estiver usando o modo nãoWSDL
7639 $options Array de opções para SoapClient O modo não WSDL requer localização e uri
para definir todas as outras opções
7640 são opcionais Veja a tabela abaixo para os valores possíveis.
7641 Seção 32.1: Modo WSDL
7642 Primeiro, crie um novo objeto SoapClient, passando a URL para o arquivo WSDL e,
opcionalmente, uma matriz de opções
7643 //Cria um novo objeto de cliente usando um URL WSDL
7644 $soap = new SoapClient ('https://example.com/soap.wsdl', [
7645 # Esse array e seus valores são opcionais
7646 'soap_version' => SOAP_1_2,
7647 'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP,
7648 'cache_wsdl' => WSDL_CACHE_BOTH,
7649 # Ajuda na depuração
7650 'trace' => TRUE,
7651 'exceções' => VERDADEIRO
7652 ]);
7653 Em seguida, use o objeto $soap para chamar seus métodos SOAP
7654 $result = $soap> requestData (['a', 'b', 'c']);
7655 Seção 32.2: Modo não WSDL
7656 Isso é semelhante ao modo WSDL, exceto que passamos NULL como o arquivo WSDL e
definimos o local e o uri
7657 opções
7658 $soap = new SoapClient (NULL, [
7659 'location' => 'https://example.com/soap/endpoint',
7660 'uri' => 'namespace'
7661 ]);
7662 Seção 32.3: Classmaps
7663 Ao criar um cliente SOAP em PHP, você também pode definir uma chave de mapa de
classe na matriz de configuração Este mapa de classes
7664 define quais tipos definidos no WSDL devem ser mapeados para classes reais, em vez
do padrão StdClass o
7665 O motivo pelo qual você gostaria de fazer isso é porque pode obter preenchimento
automático de campos e chamadas de método nesses
7666 classes, em vez de ter que adivinhar quais campos são definidos no StdClass regular
7667 class MyAddress {
7668 público $country;
7669 cidade pública $;
7670 public $full_name;
7671 public $postal_code; //ou zip_code
7672 public $house_number;
7673 }
7674 class MyBook {
7675 nome $público;
7676 public $author;
7677 FF
7678 Notas PHP para Profissionais 188
7679 //O classmap também nos permite adicionar funções úteis aos objetos
7680 //que são retornados das operações SOAP
7681 função pública getShortDescription () {
7682 return "{$this> name}, escrito por {$this> author}";
7683 }
7684 }
7685 $soap_client = new SoapClient ($link_to_wsdl, [
7686 //Outros parâmetros
7687 "classmap" => [
7688 "Endereço" => MyAddress :: class, //:: class simple retorna a classe como string
7689 "Livro" => MyBook :: class,
7690 ]
7691 ]);
7692 Depois de configurar o classmap, sempre que você executar uma determinada operação
que retorne um tipo Address ou Book, o
7693 O SoapClient irá instanciar essa classe, preencher os campos com os dados e
retornálos da chamada de operação
7694 //Vamos supor que 'getAddress (1234)' retorna um endereço por ID no banco de dados
7695 $address = $soap_client> getAddress (1234);
7696 //$address agora é do tipo MyAddress devido ao classmap
7697 echo $endereço> país;
7698 //Vamos supor o mesmo para 'getBook (1234)'
7699 $book = $soap_client> getBook (124);
7700 //Não podemos usar outras funções definidas na classe MyBook
7701 echo $book> getShortDescription ();
7702 //Qualquer tipo definido no WSDL que não esteja definido no classmap
7703 //irá tornarse um regular StdClass obje ct
7704 $author = $soap_client> getAuthor (1234);
7705 //Nenhum classmap para o tipo de Autor, $author é o StdClass regular
7706 //Ainda podemos acessar campos, mas nenhum preenchimento automático e nenhuma função
personalizada
7707 //para definir os objetos
7708 echo $author> name;
7709 Seção 32.4: Solicitação e resposta do SOAP de rastreamento
7710 Às vezes, queremos ver o que é enviado e recebido na solicitação SOAP Os métodos a
seguir retornarão o
7711 XML na solicitação e resposta:
7712 SoapClient :: __ getLastRequest ()
7713 SoapClient :: __ getLastRequestHeaders ()
7714 SoapClient :: __ getLastResponse ()
7715 SoapClient :: __ getLastResponseHeaders ()
7716 Por exemplo, suponha que tenhamos uma constante de AMBIENTE e quando o valor dessa
constante é definido como DESENVOLVIMENTO
7717 deseja ecoar todas as informações quando a chamada para getAddress gera um erro Uma
solução poderia ser:
7718 experimentar {
7719 $address = $soap_client> getAddress (1234);
7720 } catch (SoapFault $e) {
7721 if (ENVIRONMENT === 'DEVELOPMENT') {
7722 var_dump (
7723 $soap_client > __ getLastRequestHeaders ()
7724 $soap_client > __ getLastRequest (),
7725 FF
7726 Notas PHP para Profissionais 189
7727 $soap_client > __ getLastResponseHeaders (),
7728 $soap_client > __ getLastResponse ()
7729 );
7730 }
7731 .
7732 }
7733 FF
7734 Notas PHP para Profissionais 190
7735 Capítulo 33: Usando o cURL em PHP
7736 Detalhes do Parâmetro
7737 curl_init Inicializa uma sessão cURL
7738 url O URL a ser usado no pedido cURL
7739 curl_setopt Defina uma opção para uma transferência cURL
7740 ch O identificador cURL (valor de retorno de curl_init ())
7741 opção CURLOPT_XXX a ser definida veja a documentação do PHP para a lista de opções
e valores aceitáveis
7742 valor O valor a ser definido no identificador cURL para a opção dada
7743 curl_exec Executa uma sessão cURL
7744 ch O identificador cURL (valor de retorno de curl_init ())
7745 curl_close Fecha uma sessão cURL
7746 ch O identificador cURL (valor de retorno de curl_init ())
7747 Seção 33.1: Uso Básico (Solicitações GET)
7748 cURL é uma ferramenta para transferir dados com sintaxe de URL Suporta HTTP, FTP,
SCP e muitos outros (curl> = 7.19.4).
7749 Lembrese, você precisa instalar e ativar a extensão cURL para usálo
7750 //uma pequena verificação de script é a extensão cURL carregada ou não
7751 if (! extension_loaded ("curl")) {
7752 die ("extensão cURL não carregada! Sair agora.");
7753 }
7754 //Início real do script
7755 //cria um novo recurso cURL
7756 //$curl é o identificador do recurso
7757 $curl = curl_init ();
7758 //define o URL e outras opções
7759 curl_setopt ($curl, CURLOPT_URL, "http://www.example.com");
7760 //executa e passa o resultado para o navegador
7761 curl_exec ($curl);
7762 //fecha o recurso cURL
7763 curl_close ($curl);
7764 Seção 33.2: solicitações de POST
7765 Se você quiser imitar a ação POST do formulário HTML, poderá usar o cURL
7766 //POST data in array
7767 $post = [
7768 'a' => 'maçã',
7769 'b' => 'banana'
7770 ];
7771 //Cria um novo recurso cURL com URL para POST
7772 $ch = curl_init ('http://www.example.com');
7773 //Definimos o parâmetro CURLOPT_RETURNTRANSFER para ler a saída
7774 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
7775 FF
7776 Notas PHP para Profissionais 191
7777 //Vamos passar dados do POST
7778 curl_setopt ($ch, CURLOPT_POSTFIELDS, $post);
7779 //Executamos nosso pedido e obtemos a saída em uma variável $response
7780 $response = curl_exec ($ch);
7781 //Fechar a conexão
7782 curl_close ($ch);
7783 Seção 33.3: Usando Cookies
7784 cURL pode manter os cookies recebidos em respostas para uso com solicitações
subsequentes Para manipulação simples de cookies de sessão
7785 na memória, isso é conseguido com uma única linha de código:
7786 curl_setopt ($ch, CURLOPT_COOKIEFILE, "");
7787 Nos casos em que você é obrigado a manter os cookies depois que o identificador cURL
é destruído, você pode especificar o arquivo a ser armazenado
7788 eles dentro:
7789 curl_setopt ($ch, CURLOPT_COOKIEJAR, "/tmp/cookies.txt");
7790 Então, quando quiser usálos novamente, passeos como o arquivo de cookie:
7791 curl_setopt ($ch, CURLOPT_COOKIEFILE, "/tmp/cookies.txt");
7792 Lembrese, porém, que essas duas etapas não são necessárias, a menos que você precise
carregar cookies entre diferentes
7793 alças cURL Para a maioria dos casos de uso, a configuração de CURLOPT_COOKIEFILE na
string vazia é tudo que você precisa.
7794 O tratamento de cookies pode ser usado, por exemplo, para recuperar recursos de um
site que requer um login Isto é
7795 tipicamente um procedimento de duas etapas Primeiro, POST para a página de login.
7796 <?php
7797 # cria um manipulador cURL
7798 $ch = curl_init ();
7799 # define o URL (isso também pode ser passado para curl_init () se desejado)
7800 curl_setopt ($ch, CURLOPT_URL, "https://www.example.com/login.php");
7801 # defina o método HTTP para POST
7802 curl_setopt ($ch, CURLOPT_POST, true);
7803 # definir esta opção para uma string vazia permite o tratamento de cookies
7804 # mas não carrega cookies de um arquivo
7805 curl_setopt ($ch, CURLOPT_COOKIEFILE, "");
7806 # define os valores a serem enviados
7807 curl_setopt ($ch, CURLOPT_POSTFIELDS, array (
7808 "username" => "joe_bloggs",
7809 "password" => "$up3r_ $3cr3t",
7810 ));
7811 # retornar o corpo da resposta
7812 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
7813 # enviar o pedido
7814 $result = curl_exec ($ch);
7815 FF
7816 Notas PHP para Profissionais 192
7817 A segunda etapa (após a verificação de erro padrão é feita) é geralmente uma
solicitação GET simples O importante é
7818 reutilize o identificador cURL existente para o segundo pedido Isso garante que os
cookies da primeira resposta sejam
7819 automaticamente incluído no segundo pedido
7820 # não estamos chamando curl_init ()
7821 # basta alterar o URL
7822 curl_setopt ($ch, CURLOPT_URL, "https://www.example.com/show_me_the_foo.php");
7823 # mudar o método de volta para GET
7824 curl_setopt ($ch, CURLOPT_HTTPGET, true);
7825 # enviar o pedido
7826 $result = curl_exec ($ch);
7827 # terminado com cURL
7828 curl_close ($ch);
7829 # faça coisas com $result .
7830 Isso serve apenas como um exemplo de manipulação de cookies Na vida real, as coisas
geralmente são mais complicadas Muitas vezes você
7831 deve executar um GET inicial da página de login para obter um token de login que
precisa ser incluído no seu POST De outros
7832 sites podem bloquear o cliente cURL com base em sua seqüência UserAgent, exigindo
que você o altere
7833 Seção 33.4: Usando o multi_curl para fazer vários POST
7834 solicitações de
7835 Às vezes, precisamos fazer muitas solicitações POST para um ou vários terminais
diferentes Para lidar com esse cenário,
7836 podemos usar o multi_curl
7837 Primeiro de tudo, criamos quantos pedidos, conforme necessário, exatamente da mesma
forma que o exemplo simples e os colocamos em
7838 uma matriz
7839 Usamos o curl_multi_init e adicionamos cada identificador a ele
7840 Neste exemplo, estamos usando 2 endpoints diferentes:
7841 //array de dados para o POST
7842 $request_contents = array ();
7843 //array de URLs
7844 $urls = array ();
7845 //array de alças cURL
7846 $chs = array ();
7847 //primeiro conteúdo do POST
7848 $request_contents [] = [
7849 'a' => 'maçã',
7850 'b' => 'banana'
7851 ];
7852 //segundo conteúdo do POST
7853 $request_contents [] = [
7854 'a' => 'peixe',
7855 'b' => 'camarão'
7856 ];
7857 //definir as urls
7858 $urls [] = 'http://www.example.com';
7859 $urls [] = 'http://www.example2.com';
7860 FF
7861 Notas PHP para Profissionais 193
7862 //cria o array de alças cURL e adiciona a um multi_curl
7863 $mh = curl_multi_init ();
7864 foreach ($urls como $key => $url) {
7865 $chs [$key] = curl_init ($url);
7866 curl_setopt ($chs [$key], CURLOPT_RETURNTRANSFER, true);
7867 curl_setopt ($chs [$key], CURLOPT_POST, true);
7868 curl_setopt ($chs [$key], CURLOPT_POSTFIELDS, $request_contents [$key]);
7869 curl_multi_add_handle ($mh, $chs [$key]);
7870 }
7871 Em seguida, usamos curl_multi_exec para enviar as solicitações
7872 //executando os pedidos
7873 $running = null;
7874 Faz {
7875 curl_multi_exec ($mh, $running);
7876 } enquanto ($correndo);
7877 //obtendo as respostas
7878 foreach (array_keys ($chs) como $key) {
7879 $error = curl_error ($chs [$key]);
7880 $last_effective_URL = curl_getinfo ($chs [$chave], CURLINFO_EFFECTIVE_URL);
7881 $time = curl_getinfo ($chs [$key], CURLINFO_TOTAL_TIME);
7882 $response = curl_multi_getcontent ($chs [$key]); //Obter resultados
7883 if (! vazio (erro $)) {
7884 echo "A requisição $key retorna um erro: $error" "\ n";
7885 }
7886 outro {
7887 echo "A solicitação para '$last_effective_URL' retornou '$response' em $time
segundos." "\ n";
7888 }
7889 curl_multi_remove_handle ($mh, $chs [$key]);
7890 }
7891 //fecha o manipulador atual
7892 curl_multi_close ($mh);
7893 Um possível retorno para este exemplo poderia ser:
7894 A solicitação para "http://www.example.com" retornou "frutas" em dois segundos
7895 A solicitação para "http://www.example2.com" retornou "frutos do mar" em 5 segundos
7896 Seção 33.5: Enviando dados multidimensionais e múltiplos
7897 arquivos com o CurlFile em um pedido
7898 Digamos que temos um formulário como o abaixo Queremos enviar os dados para o nosso
servidor web via AJAX e de lá para
7899 um script em execução em um servidor externo.
7900 FF
7901 Notas PHP para Profissionais 194
7902 Portanto, temos entradas normais, um campo de seleção múltipla e uma zona de
recebimento de arquivos, onde podemos fazer upload de vários arquivos
7903 Supondo que a requisição AJAX POST foi bem sucedida, obtemos os seguintes dados no
site PHP:
7904 //print_r ($_ POST)
7905 Matriz
7906 (
7907 [first_name] => João
7908 [last_name] => Doe
7909 [atividades] => Matriz
7910 (
7911 [0] => futebol
7912 [1] => caminhada
7913 )
7914 )
7915 e os arquivos devem ficar assim
7916 //print_r ($_ FILES)
7917 Matriz
7918 (
7919 [upload] => Array
7920 (
7921 [name] => Array
7922 (
7923 [0] => my_photo.jpg
7924 [1] => minha_vida.pdf
7925 )
7926 FF
7927 Notas PHP para Profissionais 195
7928 [type] => Matriz
7929 (
7930 [0] => imagem /jpg
7931 [1] => aplicação /pdf
7932 )
7933 [tmp_name] => Matriz
7934 (
7935 [0] => /tmp /phpW5spji
7936 [1] => /tmp /phpWgnUeY
7937 )
7938 [error] => Array
7939 (
7940 [0] => 0
7941 [1] => 0
7942 )
7943 [size] => Matriz
7944 (
7945 [0] => 647548
7946 [1] => 643223
7947 )
7948 )
7949 )
7950 Por enquanto, tudo bem Agora queremos enviar esses dados e arquivos para o servidor
externo usando cURL com a classe CurlFile
7951 Como o cURL aceita apenas um array simples, mas não multidimensional, temos que
achatar o array $_POST primeiro
7952 Para fazer isso, você pode usar essa função, por exemplo, que oferece o seguinte:
7953 //print_r ($new_post_array)
7954 Matriz
7955 (
7956 [first_name] => João
7957 [last_name] => Doe
7958 [atividades [0]] => futebol
7959 [atividades [1]] => caminhadas
7960 )
7961 O próximo passo é criar objetos CurlFile para os arquivos enviados Isso é feito pelo
seguinte loop:
7962 $files = array ();
7963 foreach ($_FILES ["upload"] ["error"] como $key => $error) {
7964 if ($error == UPLOAD_ERR_OK) {
7965 $files ["upload [$key]"] = curl_file_create (
7966 $_FILES ['upload'] ['tmp_name'] [$chave],
7967 $_FILES ['upload'] ['type'] [$key],
7968 $_FILES ['upload'] ['nome'] [tecla $]
7969 );
7970 }
7971 }
7972 curl_file_create é uma função auxiliar da classe CurlFile e cria os objetos CurlFile
Nós salvamos cada objeto no
7973 FF
7974 Notas PHP para Profissionais 196
7975 $files array com chaves chamadas "upload [0]" e "upload [1]" para nossos dois
arquivos
7976 Agora temos que combinar a matriz de postes achatada e a matriz de arquivos e
salvála como $data assim:
7977 $data = $new_post_array + $arquivos;
7978 O último passo é enviar a solicitação cURL:
7979 $ch = curl_init ();
7980 curl_setopt_array ($ch, array (
7981 CURLOPT_POST => 1,
7982 CURLOPT_URL => "https://api.externalserver.com/upload.php",
7983 CURLOPT_RETURNTRANSFER => 1,
7984 CURLINFO_HEADER_OUT => 1,
7985 CURLOPT_POSTFIELDS => $data
7986 ));
7987 $result = curl_exec ($ch);
7988 curl_close ($ch);
7989 Como os dados $agora são uma matriz simples (plana), o cURL envia automaticamente
essa solicitação POST com o Tipo de Conteúdo:
7990 multipart /formdata
7991 Em upload.php no servidor externo, agora você pode obter os dados e arquivos de
postagem com $_POST e $_FILES como você faria
7992 normalmente faz
7993 Seção 33.6: Criando e enviando uma solicitação com um personalizado
7994 método
7995 Por padrão, o PHP Curl suporta solicitações GET e POST Também é possível enviar
solicitações personalizadas, como DELETE,
7996 PUT ou PATCH (ou métodos não padrão) usando o parâmetro CURLOPT_CUSTOMREQUEST
7997 $method = 'DELETE'; //Cria um pedido DELETE
7998 $ch = curl_init ($url);
7999 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
8000 curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $método);
8001 $content = curl_exec ($ch);
8002 curl_close ($ch);
8003 Seção 33.7: Obter e definir cabeçalhos http personalizados no php
8004 Enviando o cabeçalho da solicitação
8005 $uri = 'http: //localhost/http.php';
8006 $ch = curl_init ($uri);
8007 curl_setopt_array ($ch, array (
8008 CURLOPT_HTTPHEADER => array ('XUser: admin', 'XAuthorization: 123456'),
8009 CURLOPT_RETURNTRANSFER => verdadeiro
8010 CURLOPT_VERBOSE => 1
8011 ));
8012 $out = curl_exec ($ch);
8013 curl_close ($ch);
8014 //saída de resposta de eco
8015 echo $out;
8016 FF
8017 Notas PHP para Profissionais 197
8018 Lendo o cabeçalho customizado
8019 print_r (apache_request_headers ());
8020 Saída:
8021 Matriz
8022 (
8023 [Host] => localhost
8024 [Aceitar] => */*
8025 [XUser] => admin
8026 [Autorização X] => 123456
8027 [ContentLength] => 9
8028 [ContentType] => aplicativo /xwwwformurlencoded
8029 )
8030 Também podemos enviar o cabeçalho usando a sintaxe abaixo:
8031 curl header "XMyHeader: 123" www.google.com.br
8032 FF
8033 Notas PHP para Profissionais 198
8034 Capítulo 34: Reflexão
8035 Seção 34.1: Detecção de recurso de classes ou objetos
8036 A detecção de características de classes pode ser feita parcialmente com as funções
property_exists e method_exists
8037 class MyClass {
8038 public $public_field;
8039 protected $protected_field;
8040 private $private_field;
8041 static static_field;
8042 Const CONSTANT = 0;
8043 public function public_function () {}
8044 função protegida protected_function () {}
8045 função privada private_function () {}
8046 função estática static_function () {}
8047 }
8048 //check properties
8049 $check = property_exists ('MyClass', 'public_field'); //verdade
8050 $check = property_exists ('MyClass', 'protected_field'); //verdade
8051 $check = property_exists ('MyClass', 'private_field'); //true, a partir do PHP 5.3.0
8052 $check = property_exists ('MyClass', 'static_field'); //verdade
8053 $check = property_exists ('MyClass', 'other_field'); //false
8054 //verificar métodos
8055 $check = method_exists ('MyClass', 'public_function'); //verdade
8056 $check = method_exists ('MyClass', 'protected_function'); //verdade
8057 $check = method_exists ('MyClass', 'private_function'); //verdade
8058 $check = method_exists ('MyClass', 'static_function'); //verdade
8059 //Contudo.
8060 $check = property_exists ('MyClass', 'CONSTANT'); //false
8061 $check = property_exists ($objeto, 'CONSTANT'); //false
8062 Com um ReflectionClass, também constantes podem ser detectadas:
8063 $r = new ReflectionClass ('MyClass');
8064 $check = $r> hasProperty ('public_field'); //verdade
8065 $check = $r> hasMethod ('public_function'); //verdade
8066 $check = $r> hasConstant ('CONSTANT'); //verdade
8067 //também funciona para membros protegidos, privados e /ou estáticos
8068 Nota: para property_exists e method_exists, também pode ser fornecido um objeto da
classe de interesse em vez do
8069 nome da classe Usando reflexão, a classe ReflectionObject deve ser usada em vez de
ReflectionClass.
8070 Seção 34.2: Testando métodos privados /protegidos
8071 Às vezes é útil testar métodos privados e protegidos, assim como os públicos
8072 carro da classe
8073 {
8074 /**
8075 * @param mixed $argument
8076 *
8077 * @return misturado
8078 */
8079 unidade de função protegida (argumento $)
8080 FF
8081 Notas PHP para Profissionais 199
8082 {
8083 return $argumento;
8084 }
8085 /**
8086 * @return bool
8087 */
8088 Parada de função estática privada ()
8089 {
8090 retorno verdadeiro;
8091 }
8092 }
8093 A maneira mais fácil de testar o método da unidade é usar a reflexão
8094 classe DriveTest
8095 {
8096 /**
8097 * @teste
8098 */
8099 função pública testDrive ()
8100 {
8101 //prepare
8102 $argument = 1;
8103 $expected = $argumento;
8104 $car = new \ Car ();
8105 $reflection = new ReflectionClass (\ Car :: class);
8106 $method = $reflection> getMethod ('drive');
8107 $method> setAccessible (true);
8108 //invoca a lógica
8109 $result = $method> invokeArgs ($carro, [argumento $]);
8110 //teste
8111 $this> assertEquals ($esperado, $resultado);
8112 }
8113 }
8114 Se o método é estático, você passa null no lugar da instância da classe
8115 class StopTest
8116 {
8117 /**
8118 * @teste
8119 */
8120 função pública testStop ()
8121 {
8122 //prepare
8123 $esperado = verdadeiro;
8124 $reflection = new ReflectionClass (\ Car :: class);
8125 $method = $reflection> getMethod ('stop');
8126 $method> setAccessible (true);
8127 //invoca a lógica
8128 $result = $method> invoke (nulo);
8129 //teste
8130 $this> assertEquals ($esperado, $resultado);
8131 }
8132 FF
8133 Notas PHP para Profissionais 200
8134 }
8135 Seção 34.3: Acessando membros privados e protegidos
8136 variáveis
8137 A reflexão é frequentemente usada como parte de testes de software, como para a
criação /instanciação de tempo de tempo de objetos simulados
8138 Também é ótimo para inspecionar o estado de um objeto em um determinado ponto no
tempo Aqui está um exemplo de usar Reflexão
8139 em um teste de unidade para verificar se um membro de classe protegido contém o
valor esperado
8140 Abaixo está uma classe muito básica para um carro Ele tem uma variável de membro
protegida que conterá o valor que representa o
8141 cor do carro Como a variável de membro está protegida, não podemos acessála
diretamente e devemos usar um getter e
8142 setter método para recuperar e definir seu valor respectivamente
8143 carro da classe
8144 {
8145 cor $protegida
8146 função pública setColor ($color)
8147 {
8148 $this> color = $color;
8149 }
8150 função pública getColor ($color)
8151 {
8152 retorne $this> color;
8153 }
8154 }
8155 Para testar isso, muitos desenvolvedores irão criar um objeto Car, definir a cor do
carro usando Car :: setColor (), recuperar a cor
8156 usando Car :: getColor () e compare esse valor com a cor definida:
8157 /**
8158 * @teste
8159 * @covers \ Car :: setColor
8160 */
8161 Função pública testSetColor ()
8162 {
8163 $color = 'vermelho';
8164 $car = new \ Car ();
8165 $car> setColor ($color);
8166 $getColor = $car> getColor ();
8167 $this> assertEquals ($color, $reflectionColor);
8168 }
8169 Na superfície, isso parece bem Afinal, tudo Car :: getColor () faz é retornar o
valor do membro protegido
8170 variável Car :: $color Mas este teste é falho de duas maneiras:
8171 1 Exercita Car :: getColor () que está fora do escopo deste teste
8172 2 Depende de Car :: getColor () que pode ter um bug em si que pode fazer com que o
teste tenha um falso positivo ou
8173 negativo
8174 Vejamos por que não devemos usar o Car :: getColor () em nosso teste de unidade e
devemos usar o Reflection Vamos dizer um
8175 Ao desenvolvedor é atribuída uma tarefa para adicionar "Metálico" a cada cor de
carro Então eles tentam modificar o Car :: getColor () para
8176 prefixar "Metallic" à cor do carro:
8177 FF
8178 Notas PHP para Profissionais 201
8179 carro da classe
8180 {
8181 cor $protegida
8182 função pública setColor ($color)
8183 {
8184 $this> color = $color;
8185 }
8186 função pública getColor ($color)
8187 {
8188 return "Metálico"; $this> color;
8189 }
8190 }
8191 Você vê o erro? O desenvolvedor usou um pontoevírgula em vez do operador de
concatenação em uma tentativa de
8192 prefixar "Metálico" à cor do carro Como resultado, sempre que Car :: getColor () é
chamado, "Metallic" será retornado
8193 independentemente da cor real do carro Como resultado, nosso teste de unidade Car ::
setColor () falhará
8194 Car :: setColor () funciona perfeitamente e não foi afetado por essa mudança
8195 Então, como podemos verificar Car :: $color contém o valor que estamos definindo via
Car :: setColor ()? Nós podemos usar Refelection para
8196 inspecione a variável de membro protegida diretamente Então, como fazemos isso? Nós
podemos usar Refelection para fazer o
8197 variável de membro protegido acessível ao nosso código para que ele possa recuperar
o valor
8198 Vamos ver o código primeiro e depois desmembrálo:
8199 /**
8200 * @teste
8201 * @covers \ Car :: setColor
8202 */
8203 Função pública testSetColor ()
8204 {
8205 $color = 'vermelho';
8206 $car = new \ Car ();
8207 $car> setColor ($color);
8208 $reflectionOfCar = new \ ReflectionObject ($car);
8209 $protectedColor = $reflectionOfForm> getProperty ('color');
8210 $protectedColor> setAccessible (true);
8211 $reflectionColor = $protectedColor> getValue ($carro);
8212 $this> assertEquals ($color, $reflectionColor);
8213 }
8214 Aqui está como estamos usando o Reflection para obter o valor de Car :: $color no
código acima:
8215 1 Criamos um novo ReflectionObject representando nosso objeto Car
8216 2 Obtemos um ReflectionProperty para Car :: $color (isso "representa" a variável Car
:: $color)
8217 3 Nós fazemos o carro :: $cor acessível
8218 4 Obtemos o valor de Car :: $color
8219 Como você pode ver usando o Reflection, podemos obter o valor de Car :: $color sem
precisar chamar Car :: getColor () ou
8220 qualquer outra função acessadora que possa causar resultados de teste inválidos
Agora nosso teste de unidade para Car :: setColor () é seguro
8221 e preciso.
8222 FF
8223 Notas PHP para Profissionais 202
8224 Capítulo 35: Injeção de Dependência
8225 Injeção de dependência (DI) é um termo chique para "passar as coisas em" Tudo o que
realmente significa é passar as dependências de um
8226 objeto através do construtor e /ou setters em vez de criálos na criação do objeto
dentro do objeto
8227 Injeção de Dependência também pode se referir a Contêineres de Injeção de
Dependência que automatizam a construção e
8228 injeção
8229 Seção 35.1: Injeção de Construtor
8230 Objetos geralmente dependem de outros objetos Em vez de criar a dependência no
construtor, a dependência
8231 deve ser passado para o construtor como um parâmetro Isso garante que não haja
acoplamento entre os objetos,
8232 e permite alterar a dependência na instanciação de classes Isto tem uma série de
benefícios, incluindo fazer
8233 código mais fácil de ler, tornando as dependências explícitas, bem como tornando o
teste mais simples, já que as dependências
8234 pode ser trocado e ridicularizado mais facilmente
8235 No exemplo a seguir, Component dependerá de uma instância do Logger, mas não criará
uma Requer um
8236 para ser passado como argumento para o construtor
8237 logger de interface {
8238 log de função pública (string $message);
8239 }
8240 class Component {
8241 $logger privado;
8242 função pública __construct (Logger $logger) {
8243 $this> logger = $logger;
8244 }
8245 }
8246 Sem injeção de dependência, o código provavelmente seria semelhante a:
8247 class Component {
8248 $logger privado;
8249 função pública __construct () {
8250 $this> logger = novo FooLogger ();
8251 }
8252 }
8253 Usar new para criar novos objetos no construtor indica que a injeção de dependência
não foi usada (ou foi usada
8254 incompletamente), e que o código está fortemente acoplado É também um sinal de que o
código está incompletamente testado ou pode ter
8255 testes frágeis que fazem suposições incorretas sobre o estado do programa
8256 No exemplo acima, onde estamos usando injeção de dependência, poderíamos facilmente
mudar para um diferente
8257 Logger se isso for necessário Por exemplo, podemos usar uma implementação do Agente
de Log que registra em um
8258 local, ou que usa um formato de log diferente, ou que registra no banco de dados em
vez de em um arquivo
8259 Seção 35.2: Injeção Setter
8260 Dependências também podem ser injetadas por setters
8261 logger de interface {
8262 log de função pública (mensagem $);
8263 }
8264 FF
8265 Notas PHP para Profissionais 203
8266 class Component {
8267 $logger privado;
8268 private $databaseConnection;
8269 função pública __construct (DatabaseConnection $databaseConnection) {
8270 $this> databaseConnection = $databaseConnection;
8271 }
8272 função pública setLogger (Logger $logger) {
8273 $this> logger = $logger;
8274 }
8275 núcleo de função pública () {
8276 $this> logSave ();
8277 return $this> databaseConnection> save ($this);
8278 }
8279 função pública logSave () {
8280 if ($this> logger) {
8281 $this> logger> log ('salvar');
8282 }
8283 }
8284 }
8285 Isso é especialmente interessante quando a funcionalidade principal da classe não
depende da dependência para funcionar
8286 Aqui, a única dependência necessária é o DatabaseConnection, portanto, está no
construtor A dependência do Logger é
8287 opcional e, portanto, não precisa fazer parte do construtor, facilitando o uso da
classe
8288 Observe que, ao usar a injeção setter, é melhor estender a funcionalidade em vez de
substituíla Ao definir um
8289 dependência, não há nada que confirme que a dependência não vai mudar em algum
momento, o que poderia levar em
8290 resultados inesperados Por exemplo, um FileLogger pode ser configurado primeiro e,
em seguida, um MailLogger pode ser definido este
8291 interrompe o encapsulamento e torna os logs difíceis de encontrar, porque estamos
substituindo a dependência
8292 Para evitar isso, devemos adicionar uma dependência com injeção de setter, assim:
8293 logger de interface {
8294 log de função pública (mensagem $);
8295 }
8296 class Component {
8297 $loggers privados = array ();
8298 private $databaseConnection;
8299 função pública __construct (DatabaseConnection $databaseConnection) {
8300 $this> databaseConnection = $databaseConnection;
8301 }
8302 public function addLogger (Logger $logger) {
8303 $this> loggers [] = $logger;
8304 }
8305 núcleo de função pública () {
8306 $this> logSave ();
8307 return $this> databaseConnection> save ($this);
8308 }
8309 função pública logSave () {
8310 foreach ($this> loggers como $logger) {
8311 $logger> log ('salvar');
8312 FF
8313 Notas PHP para Profissionais 204
8314 }
8315 }
8316 }
8317 Assim, sempre que usarmos a funcionalidade principal, ela não será quebrada mesmo se
não houver dependência do agente de log adicionado e
8318 qualquer registrador adicionado será usado mesmo que outro registrador possa ter
sido adicionado Estamos estendendo a funcionalidade
8319 em vez de substituílo
8320 Seção 35.3: Injeção de Contêiner
8321 Injeção de Dependência (DI) no contexto do uso de um Container de Injeção de
Dependência (DIC) pode ser visto como um superconjunto
8322 de injeção de construtor Um DIC normalmente analisará as dicas de tipo de um
construtor de classe e resolverá suas necessidades, de forma eficaz.
8323 injetando as dependências necessárias para a execução da instância
8324 A implementação exata vai muito além do escopo deste documento, mas em seu coração,
um DIC depende do uso
8325 a assinatura de uma aula .
8326 documentação do namespace;
8327 Exemplo de classe
8328 {
8329 significado $privado;
8330 função pública __construct (significado $significado)
8331 {
8332 $this> meaning = $meaning;
8333 }
8334 }
8335 .para instanciálo automaticamente, confiando a maior parte do tempo em um sistema de
carregamento automático
8336 //versões mais antigas do PHP
8337 $container> make ('Documentação \ Exemplo');
8338 //desde o PHP 5.5
8339 $container> make (\ Documentation \ Example :: class);
8340 Se você estiver usando PHP na versão 5.5 e quiser obter o nome de uma classe da
maneira mostrada acima,
8341 A maneira correta é a segunda abordagem Dessa forma, você pode rapidamente encontrar
usos da classe usando IDEs modernos, que
8342 te ajudará muito com refatoração em potencial Você não quer depender de strings
regulares.
8343 Neste caso, a Documentação \ Exemplo sabe que precisa de um Significado, e um DIC
por sua vez instanciará um Significado
8344 tipo A implementação concreta não precisa depender da instância de consumo.
8345 Em vez disso, definimos regras no contêiner, antes da criação do objeto, que instrui
como tipos específicos devem ser
8346 instanciado se necessário
8347 Isto tem uma série de vantagens, como um DIC pode
8348 Compartilhar instâncias comuns
8349 Fornecer uma fábrica para resolver uma assinatura de tipo
8350 Resolver uma assinatura de interface
8351 Se definirmos regras sobre como tipos específicos precisam ser gerenciados, podemos
obter um controle preciso sobre quais tipos são
8352 compartilhada, instanciada ou criada a partir de uma fábrica.
8353 FF
8354 Notas PHP para Profissionais 205
8355 Capítulo 36: XML
8356 Seção 36.1: Criar um XML usando o DomDocument
8357 Para criar um XML usando DOMDocument, basicamente, precisamos criar todas as tags e
atributos usando o
8358 Os métodos createElement () e createAttribute () criam a estrutura XML com o
appendChild ()
8359 O exemplo abaixo inclui tags, atributos, uma seção CDATA e um namespace diferente
para a segunda tag:
8360 $dom = new DOMDocument ('1.0', 'utf8');
8361 $dom> preserveWhiteSpace = false;
8362 $dom> formatOutput = true;
8363 //cria as tags principais, sem valores
8364 $books = $dom> createElement ('livros');
8365 $book_1 = $dom> createElement ('book');
8366 //cria algumas tags com valores
8367 $name_1 = $dom> createElement ('nome', 'PHP Uma Introdução');
8368 $price_1 = $dom> createElement ('price', '$5.95');
8369 $id_1 = $dom> createElement ('id', '1');
8370 //criar e anexar um atributo
8371 $attr_1 = $dom> createAttribute ('versão');
8372 $attr_1> valor = '1,0';
8373 //acrescentar o atributo
8374 $id_1> appendChild ($attr_1);
8375 //cria o segundo livro de tags com namespace diferente
8376 $namespace = 'www.example.com/libraryns/1.0';
8377 //inclui o prefixo do namespace na tag books
8378 $books> setAttributeNS ('http://www.w3.org/2000/xmlns/', 'xmlns: ns', $namespace);
8379 $book_2 = $dom> createElementNS ($namespace, 'ns: book');
8380 $name_2 = $dom> createElementNS ($namespace, 'ns: name');
8381 //cria uma seção CDATA (que é outra instância do DOMNode) e a coloca dentro da tag
de nome
8382 $name_cdata = $dom> createCDATASection ('PHP Avançado');
8383 $name_2> appendChild ($name_cdata);
8384 $price_2 = $dom> createElementNS ($namespace, 'ns: preço', '$25.00');
8385 $id_2 = $dom> createElementNS ($namespace, 'ns: id', '2');
8386 //cria a estrutura XML
8387 $books> appendChild ($book_1);
8388 $book_1> appendChild ($name_1);
8389 $book_1> appendChild ($price_1);
8390 $book_1> appendChild ($id_1);
8391 $books> appendChild ($book_2);
8392 $book_2> appendChild ($name_2);
8393 $book_2> appendChild ($price_2);
8394 $book_2> appendChild ($id_2);
8395 $dom> appendChild ($books);
8396 //O método saveXML () retorna o XML em uma string
8397 print_r ($dom> saveXML ());
8398 Isso produzirá o seguinte XML:
8399 FF
8400 Notas PHP para Profissionais 206
8401 <? xml version = "1.0" encoding = "utf8"?>
8402 <books xmlns: ns = "www.example.com/libraryns/1.0">
8403 <book>
8404 <name> PHP Uma Introdução </name>
8405 <preço> US $5,95 </price>
8406 <id version = "1.0"> 1 </id>
8407 </book>
8408 <ns: livro>
8409 <ns: name> <! [CDATA [PHP Avançado]]> </ns: name>
8410 <ns: preço> US $25,00 </ns: preço>
8411 <ns: id> 2 </ns: id>
8412 </ns: livro>
8413 </books>
8414 Seção 36.2: Ler um documento XML com DOMDocument
8415 Da mesma forma que o SimpleXML, você pode usar DOMDocument para analisar XML de uma
string ou de um arquivo XML
8416 1 De uma string
8417 $doc = new DOMDocument ();
8418 $doc> loadXML ($string);
8419 2 De um arquivo
8420 $doc = new DOMDocument ();
8421 $doc> load ('books.xml') //usa o caminho real do arquivo Absoluto ou relativo
8422 Exemplo de análise
8423 Considerando o seguinte XML:
8424 <? xml version = "1.0" encoding = "UTF8"?>
8425 <books>
8426 <book>
8427 <name> PHP Uma Introdução </name>
8428 <preço> US $5,95 </price>
8429 <id> 1 </id>
8430 </book>
8431 <book>
8432 <nome> PHP Avançado </name>
8433 <preço> US $25,00 </price>
8434 <id> 2 </id>
8435 </book>
8436 </books>
8437 Este é um código de exemplo para analisálo
8438 $books = $doc> getElementsByTagName ('livro');
8439 foreach ($books como $book) {
8440 $title = $book> getElementsByTagName ('name') > item (0) > nodeValue;
8441 $price = $book> getElementsByTagName ('price') > item (0) > nodeValue;
8442 $id = $book> getElementsByTagName ('id') > item (0) > nodeValue;
8443 print_r ("O título do livro $id é $title e custa $price." "\ n");
8444 }
8445 Isto irá produzir:
8446 FF
8447 Notas PHP para Profissionais 207
8448 O título do livro 1 é PHP An Introduction e custa US $5,95
8449 O título do livro 2 é PHP Advanced e custa US $25,00
8450 Seção 36.3: Aproveitando o XML com a biblioteca SimpleXML do PHP
8451 SimpleXML é uma poderosa biblioteca que converte strings XML em um objeto PHP fácil
de usar
8452 O seguinte assume uma estrutura XML como abaixo
8453 <? xml version = "1.0" encoding = "UTF8"?>
8454 <document>
8455 <book>
8456 <bookName> Exemplo de StackOverflow SimpleXML </bookName>
8457 <bookAuthor> Programador PHP </bookAuthor>
8458 </book>
8459 <book>
8460 <bookName> Outro exemplo de SimpleXML </bookName>
8461 <bookAuthor> Comunidade de estouro de pilha </bookAuthor>
8462 <bookAuthor> Programador PHP </bookAuthor>
8463 <bookAuthor> FooBar </bookAuthor>
8464 </book>
8465 </document>
8466 Leia nossos dados no SimpleXML
8467 Para começar, precisamos ler nossos dados no SimpleXML Podemos fazer isso de 3
maneiras diferentes Em primeiro lugar, podemos carregar o nosso
8468 dados de um nó DOM
8469 $xmlElement = simplexml_import_dom ($domNode);
8470 Nossa próxima opção é carregar nossos dados de um arquivo XML
8471 $xmlElement = simplexml_load_file ($filename);
8472 Por fim, podemos carregar nossos dados de uma variável
8473 $xmlString = '<? xml version = "1.0" codificação = "UTF8"?>
8474 <document>
8475 <book>
8476 <bookName> Exemplo de StackOverflow SimpleXML </bookName>
8477 <bookAuthor> Programador PHP </bookAuthor>
8478 </book>
8479 <book>
8480 <bookName> Outro exemplo de SimpleXML </bookName>
8481 <bookAuthor> Comunidade de estouro de pilha </bookAuthor>
8482 <bookAuthor> Programador PHP </bookAuthor>
8483 <bookAuthor> FooBar </bookAuthor>
8484 </book>
8485 </document> ';
8486 $xmlElement = simplexml_load_string ($xmlString);
8487 Se você escolheu para carregar a partir de um elemento DOM, de um arquivo ou de uma
string, agora você tem um
8488 Variável SimpleXMLElement chamada $xmlElement Agora, podemos começar a usar nosso
XML no PHP.
8489 Acessando nossos dados SimpleXML
8490 FF
8491 Notas PHP para Profissionais 208
8492 A maneira mais simples de acessar dados em nosso objeto SimpleXMLElement é chamar as
propriedades diretamente Se quisermos
8493 acessar nosso primeiro bookName, StackOverflow SimpleXML Exemplo, então podemos
acessálo conforme abaixo
8494 echo $xmlElement> book> bookName;
8495 Neste ponto, o SimpleXML assumirá que, porque não explicamos qual livro queremos,
queremos
8496 o primeiro No entanto, se decidirmos que não queremos o primeiro, em vez disso,
queremos outro SimpleXML
8497 Exemplo, então podemos acessálo conforme abaixo
8498 echo $xmlElement> book [1] > bookName;
8499 Vale a pena notar que usar [0] funciona da mesma forma que não usálo, então
8500 $xmlElement> book
8501 funciona da mesma
8502 $xmlElement> livro [0]
8503 Looping através do nosso XML
8504 Existem muitas razões pelas quais você pode querer passar por XML, por exemplo, ter
vários itens, livros em nosso
8505 caso, que gostaríamos de exibir em uma página da web Para isso, podemos usar um loop
foreach ou um padrão para loop,
8506 vantagem da função de contagem do SimpleXMLElement
8507 foreach ($xmlElement> livro como $thisBook) {
8508 echo $thisBook> bookName
8509 }
8510 ou
8511 $count = $xmlElement> count ();
8512 para ($i = 0; $i <$count; $i ++) {
8513 echo $xmlElement> book [$i] > bookName;
8514 }
8515 Manipulando Erros
8516 Agora chegamos tão longe, é importante perceber que somos apenas humanos e
provavelmente encontraremos um erro
8517 eventualmente especialmente se estamos jogando com arquivos XML diferentes o tempo
todo E assim, vamos querer lidar com aqueles
8518 erros
8519 Considere que criamos um arquivo XML Você notará que, embora esse XML seja muito
parecido com o que tínhamos anteriormente, o problema
8520 com este arquivo XML é que a tag de fechamento final é /doc em vez de /document
8521 <? xml version = "1.0" encoding = "UTF8"?>
8522 <document>
8523 <book>
8524 <bookName> Exemplo de StackOverflow SimpleXML </bookName>
8525 <bookAuthor> Programador PHP </bookAuthor>
8526 </book>
8527 <book>
8528 <bookName> Outro exemplo de SimpleXML </bookName>
8529 <bookAuthor> Comunidade de estouro de pilha </bookAuthor>
8530 <bookAuthor> Programador PHP </bookAuthor>
8531 <bookAuthor> FooBar </bookAuthor>
8532 FF
8533 Notas PHP para Profissionais 209
8534 </book>
8535 </doc>
8536 Agora, digamos, nós carregamos isso no nosso PHP como $file
8537 libxml_use_internal_errors (true);
8538 $xmlElement = simplexml_load_file ($file);
8539 if ($xmlElement === false) {
8540 $errors = libxml_get_errors ();
8541 foreach ($errors as $thisError) {
8542 switch ($thisError> nível) {
8543 case LIBXML_ERR_FATAL:
8544 eco "ERRO FATAL:";
8545 pausa;
8546 case LIBXML_ERR_ERROR:
8547 echo "Erro não fatal:";
8548 pausa;
8549 case LIBXML_ERR_WARNING:
8550 echo "Aviso:";
8551 pausa;
8552 }
8553 echo $thisError> código PHP_EOL.
8554 'Mensagem: ' $thisError> message PHP_EOL.
8555 'Linha: ' $thisError> linha PHP_EOL.
8556 'Coluna:' $thisError> coluna PHP_EOL.
8557 'Arquivo: ' $thisError> arquivo;
8558 }
8559 libxml_clear_errors ();
8560 } outro {
8561 eco 'Happy Days';
8562 }
8563 Seremos recebidos com o seguinte
8564 ERRO FATAL: 76
8565 Mensagem: Incompatibilidade de tags de abertura e finalização: linha de documento 2
e doc
8566 Linha: 13
8567 Coluna: 10
8568 Arquivo: filepath /filename.xml
8569 No entanto, assim que resolvermos este problema, somos apresentados a "Happy Days"
8570 Seção 36.4: Criar um arquivo XML usando o XMLWriter
8571 Instanciar um objeto XMLWriter:
8572 $xml = new XMLWriter ();
8573 Em seguida, abra o arquivo no qual você deseja gravar Por exemplo, para gravar em
/var/www/example.com/xml/output.xml,
8574 usar:
8575 $xml> openUri ('file: ///var/www/example.com/xml/output.xml');
8576 Para iniciar o documento (crie a tag de abertura XML):
8577 $xml> startDocument ('1.0', 'utf8');
8578 FF
8579 Notas PHP para Profissionais 210
8580 Isto irá produzir:
8581 <? xml version = "1.0" encoding = "UTF8"?>
8582 Agora você pode começar a escrever elementos:
8583 $xml> writeElement ('foo', 'bar');
8584 Isso irá gerar o XML:
8585 <foo> bar </foo>
8586 Se você precisa de algo um pouco mais complexo do que simplesmente nós com valores
simples, você também pode "iniciar" um elemento
8587 e adicione atributos a ele antes de fechálo:
8588 $xml> startElement ('foo');
8589 $xml> writeAttribute ('bar', 'baz');
8590 $xml> writeCdata ('Lorem ipsum');
8591 $xml> endElement ();
8592 Isto irá produzir:
8593 <foo bar = "baz"> <! [CDATA [Lorem ipsum]]> </foo>
8594 Seção 36.5: Ler um documento XML com o SimpleXML
8595 Você pode analisar XML de uma string ou de um arquivo XML
8596 1 De uma string
8597 $xml_obj = simplexml_load_string ($string);
8598 2 De um arquivo
8599 $xml_obj = simplexml_load_file ('books.xml');
8600 Exemplo de análise
8601 Considerando o seguinte XML:
8602 <? xml version = "1.0" encoding = "UTF8"?>
8603 <books>
8604 <book>
8605 <name> PHP Uma Introdução </name>
8606 <preço> US $5,95 </price>
8607 <id> 1 </id>
8608 </book>
8609 <book>
8610 <nome> PHP Avançado </name>
8611 <preço> US $25,00 </price>
8612 <id> 2 </id>
8613 </book>
8614 </books>
8615 Este é um código de exemplo para analisálo
8616 FF
8617 Notas PHP para Profissionais 211
8618 $xml = simplexml_load_string ($xml_string);
8619 $books = $xml> livro;
8620 foreach ($books como $book) {
8621 $id = $book> id;
8622 $title = $book> nome;
8623 $price = $book> price;
8624 print_r ("O título do livro $id é $title e custa $price." "\ n");
8625 }
8626 Isto irá produzir:
8627 O título do livro 1 é PHP An Introduction e custa US $5,95
8628 O título do livro 2 é PHP Advanced e custa US $25,00.
8629 FF
8630 Notas PHP para Profissionais 212
8631 Capítulo 37: SimpleXML
8632 Seção 37.1: Carregando dados XML em simplexml
8633 Carregando da string
8634 Use simplexml_load_string para criar um SimpleXMLElement a partir de uma string:
8635 $xmlString = "<? xml version = '1.0' codificação = 'UTF8'?>";
8636 $xml = simplexml_load_string ($xmlString) ou morrer ("Erro: Não é possível criar
objeto");
8637 Note que ou não || deve ser usado aqui porque a precedência de ou é maior que = O
código após ou será apenas
8638 executado se $xml finalmente for resolvido como falso
8639 Carregando do arquivo
8640 Use simplexml_load_file para carregar dados XML de um arquivo ou URL:
8641 $xml = simplexml_load_string ("filePath.xml");
8642 $xml = simplexml_load_string ("https://example.com/doc.xml");
8643 A URL pode ser de qualquer esquema que o PHP suporte ou wrappers de fluxo
customizados.
8644 FF
8645 Notas PHP para Profissionais 213
8646 Capítulo 38: Analisando HTML
8647 Seção 38.1: Analisando HTML de uma string
8648 O PHP implementa um analisador compatível com o DOM Nível 2, permitindo que você
trabalhe com HTML usando métodos familiares como
8649 getElementById () ou appendChild ()
8650 $html = '<html> <body> <span id = "text"> Olá, Mundo! </span> </body> </html>';
8651 $doc = new DOMDocument ();
8652 libxml_use_internal_errors (true);
8653 $doc> loadHTML ($html);
8654 echo $doc> getElementById ("text") > textContent;
8655 Saídas:
8656 Olá Mundo!
8657 Observe que o PHP emitirá avisos sobre qualquer problema com o HTML, especialmente
se você estiver importando um documento
8658 fragmento Para evitar esses avisos, diga à biblioteca DOM (libxml) para manipular
seus próprios erros chamando
8659 libxml_use_internal_errors () antes de importar seu HTML Você pode então usar
libxml_get_errors () para manipular
8660 erros, se necessário
8661 Seção 38.2: Usando o XPath
8662 $html = '<html> <body> <span class = "text"> Olá, Mundo! </span> </body> </html>';
8663 $doc = new DOMDocument ();
8664 $doc> loadHTML ($html);
8665 $xpath = new DOMXPath ($doc);
8666 $span = $xpath> query ("//span [@ class = 'texto']") > item (0);
8667 echo $span> textContent;
8668 Saídas:
8669 Olá Mundo!
8670 Seção 38.3: SimpleXML
8671 Apresentação
8672 SimpleXML é uma biblioteca PHP que fornece uma maneira fácil de trabalhar com
documentos XML (especialmente leitura e
8673 iterando através de dados XML)
8674 A única restrição é que o documento XML deve ser bem formado
8675 Analisando XML usando abordagem processual
8676 //Carrega uma string XML
8677 $xmlstr = file_get_contents ('library.xml');
8678 FF
8679 Notas PHP para Profissionais 214
8680 $library = simplexml_load_string ($xmlstr);
8681 //Carrega um arquivo XML
8682 $library = simplexml_load_file ('library.xml');
8683 //Você pode carregar um caminho de arquivo local ou um URL válido (se
allow_url_fopen estiver definido como "On" no php.ini
8684 Analisando XML usando a abordagem OOP
8685 //$isPathToFile: informa ao construtor que o primeiro argumento representa o caminho
para um arquivo,
8686 //em vez de uma string que contenha os próprios dados XML
8687 //Carrega uma string XML
8688 $xmlstr = file_get_contents ('library.xml');
8689 $library = new SimpleXMLElement ($xmlstr);
8690 //Carrega um arquivo XML
8691 $library = new SimpleXMLElement ('library.xml', NULL, true);
8692 //$isPathToFile: informa ao construtor que o primeiro argumento representa o caminho
para um arquivo,
8693 em vez de uma string que contenha os próprios dados XML
8694 Acessando Crianças e Atributos
8695 Quando o SimpleXML analisa um documento XML, ele converte todos os seus elementos
XML, ou nós, em propriedades do
8696 Objeto SimpleXMLElement resultante
8697 Além disso, converte atributos XML em um array associativo que pode ser acessado da
propriedade para
8698 a qual eles pertencem
8699 Quando você sabe seus nomes:
8700 $library = new SimpleXMLElement ('library.xml', NULL, true);
8701 foreach ($library> book como $book) {
8702 echo $book ['isbn'];
8703 echo $book> title;
8704 echo $book> author;
8705 echo $book> publisher;
8706 }
8707 A principal desvantagem dessa abordagem é que é necessário conhecer os nomes de cada
elemento e
8708 atributo no documento XML
8709 Quando você não sabe seus nomes (ou você não quer conhecêlos):
8710 foreach ($library> children () como $child) {
8711 echo $child> getName ();
8712 //Obter atributos deste elemento
8713 foreach ($child> attributes () como $attr) {
8714 eco '' $attr> getName () ':' $attr;
8715 }
8716 //Obter filhos
8717 foreach ($child> children () como $subchild) {
8718 eco '' $subchild> getName () ':' $subchild;
8719 }
8720 }
8721 FF
8722 Notas PHP para Profissionais 215
8723 Capítulo 39: Expressões Regulares
8724 (regexp /PCRE)
8725 Detalhes do Parâmetro
8726 $pattern uma string com uma expressão regular (padrão PCRE)
8727 Seção 39.1: correspondência Global RegExp
8728 Uma correspondência global RegExp pode ser realizada usando preg_match_all
preg_match_all retorna todos os resultados correspondentes no
8729 string de assunto (em contraste com preg_match, que retorna apenas o primeiro)
8730 A função preg_match_all retorna o número de correspondências O terceiro parâmetro
$matches conterá correspondências em
8731 formato controlado por sinalizadores que podem ser dados no quarto parâmetro
8732 Se for dada uma array, $matches irá conter array no formato similar que você teria
com preg_match, exceto que preg_match
8733 pára na primeira partida, onde preg_match_all itera na string até que a string seja
totalmente consumida e retorna
8734 resultado de cada iteração em um array multidimensional, cujo formato pode ser
controlado pelo flag no quarto argumento
8735 O quarto argumento, $flags, controla a estrutura da matriz $matches O modo padrão é
PREG_PATTERN_ORDER e
8736 possíveis sinalizadores são PREG_SET_ORDER e PREG_PATTERN_ORDER
8737 O código a seguir demonstra o uso de preg_match_all:
8738 $subject = "a1b c2d3e f4g";
8739 $pattern = '/[az] ([09]) [az] /';
8740 var_dump (preg_match_all ($padrão, $assunto, $correspondências, PREG_SET_ORDER));
//int (3)
8741 var_dump ($matches);
8742 preg_match_all ($padrão, $assunto, $correspondências); //o sinalizador é
PREG_PATTERN_ORDER por padrão
8743 var_dump ($matches);
8744 //E para referência, o mesmo regexp é executado através do preg_match ()
8745 preg_match ($pattern, $subject, $matches);
8746 var_dump ($matches);
8747 O primeiro var_dump de PREG_SET_ORDER fornece esta saída:
8748 array (3) {
8749 [0] =>
8750 array (2) {
8751 [0] =>
8752 string (3) "a1b"
8753 [1] =>
8754 string (1) "1"
8755 }
8756 [1] =>
8757 array (2) {
8758 [0] =>
8759 string (3) "c2d"
8760 [1] =>
8761 string (1) "2"
8762 }
8763 [2] =>
8764 array (2) {
8765 [0] =>
8766 string (3) "f4g"
8767 [1] =>
8768 FF
8769 Notas PHP para Profissionais 216
8770 string (1) "4"
8771 }
8772 }
8773 $matches tem três matrizes aninhadas Cada matriz representa uma correspondência, que
tem o mesmo formato que o retorno
8774 resultado de preg_match
8775 O segundo var_dump (PREG_PATTERN_ORDER) fornece esta saída:
8776 array (2) {
8777 [0] =>
8778 array (3) {
8779 [0] =>
8780 string (3) "a1b"
8781 [1] =>
8782 string (3) "c2d"
8783 [2] =>
8784 string (3) "f4g"
8785 }
8786 [1] =>
8787 array (3) {
8788 [0] =>
8789 string (1) "1"
8790 [1] =>
8791 string (1) "2"
8792 [2] =>
8793 string (1) "4"
8794 }
8795 }
8796 Quando o mesmo regexp é executado através do preg_match, a seguinte matriz é
retornada:
8797 array (2) {
8798 [0] =>
8799 string (3) "a1b"
8800 [1] =>
8801 string (1) "1"
8802 }
8803 Seção 39.2: Correspondência de strings com expressões regulares
8804 preg_match verifica se uma string corresponde à expressão regular
8805 $string = 'Esta é uma string que contém números: 12345';
8806 $isMatched = preg_match ('% ^ [azAZ] +: [09] + $%', $string);
8807 var_dump ($isMatched); //bool (true)
8808 Se você passar um terceiro parâmetro, ele será preenchido com os dados
correspondentes da expressão regular:
8809 preg_match ('% ^ ([azAZ] +): ([09] +) $%', 'Esta é uma string que contém números:
12345',
8810 $matches);
8811 //$matches agora contém resultados das correspondências de expressões regulares em
uma matriz
8812 echo json_encode ($correspondências); //["números: 12345", "números", "12345"]
8813 $matches contém uma matriz de toda a correspondência, em seguida, substrings na
expressão regular limitada por parênteses,
8814 na ordem de offset do parêntese aberto Isso significa que, se você tiver /z (a (b))
/como expressão regular, índice 0
8815 contém o zab de substring inteiro, o índice 1 contém a substring delimitada pelos
parênteses externos ab e índice 2
8816 FF
8817 Notas PHP para Profissionais 217
8818 contém os parênteses internos b
8819 Seção 39.3: Dividir string em array por uma expressão regular
8820 $string = "0 | PHP 1 | CSS 2 | HTML 3 | AJAX 4 | JSON";
8821 //[09]: qualquer caractere único no intervalo de 0 a 9
8822 //+: um ou mais de 0 a 9
8823 $array = preg_split ("/[09] + \ | /", $string, 1, PREG_SPLIT_NO_EMPTY);
8824 //Ou
8825 //[]: classe de personagem
8826 //\ d: qualquer dígito
8827 //+: um ou mais de qualquer dígito
8828 $array = preg_split ("/[\ d] + \ | /", $string, 1, PREG_SPLIT_NO_EMPTY);
8829 Saída:
8830 Matriz
8831 (
8832 [0] => PHP
8833 [1] => CSS
8834 [2] => HTML
8835 [3] => AJAX
8836 [4] => JSON
8837 )
8838 Para dividir uma string em um array simplesmente passe a string e um regexp para
preg_split (); para combinar e pesquisar, adicionando
8839 terceiro parâmetro (limite) permite que você defina o número de "correspondências"
para executar, a seqüência restante será adicionada
8840 até o final da matriz
8841 O quarto parâmetro é (flags) aqui usamos o PREG_SPLIT_NO_EMPTY que impede que nosso
array contenha
8842 quaisquer chaves /valores vazios
8843 Seção 39.4: String substituindo pela expressão regular
8844 $string = "a; b; c \ nd; e; f";
8845 //$1, $2 e $3 representam o primeiro, segundo e terceiro grupos de captura
8846 echo preg_replace ("(^ ([^;] +); ([^;] +); ([^;] +) $) m", "$3; $2; $1", $string);
8847 Saídas
8848 c; b;
8849 f; e; d
8850 Procura por tudo entre pontoevírgula e inverte a ordem
8851 Seção 39.5: String substituir por retorno de chamada
8852 preg_replace_callback funciona enviando cada grupo de captura correspondente para o
retorno de chamada definido e o substitui
8853 com o valor de retorno do retorno de chamada Isso nos permite substituir strings
baseadas em qualquer tipo de lógica.
8854 $subject = "Ele disse 123abc, eu disse 456efg, então ela disse 789hij";
8855 $regex = "/\ b (\ d +) \ w + /";
8856 //Esta função substitui as entradas correspondidas condicionalmente
8857 //dependendo do primeiro caractere do grupo de captura
8858 FF
8859 Notas PHP para Profissionais 218
8860 função regex_replace ($matches) {
8861 switch ($matches [1] [0]) {
8862 caso '7':
8863 $replacement = "<b> {$combinações [0]} </b>";
8864 pausa;
8865 padrão:
8866 $replacement = "<i> {$matches [0]} </i>";
8867 }
8868 devolver a substituição $;
8869 }
8870 $replaced_str = preg_replace_callback ($regex, "regex_replace", $assunto);
8871 print_r ($substituído_str);
8872 # Ele disse <i> 123abc </i>, eu disse <i> 456efg </i>, então ela disse <b> 789hij </b>
8873 FF
8874 Notas PHP para Profissionais 219
8875 Capítulo 40: Características
8876 Seção 40.1: O que é uma característica?
8877 PHP só permite herança única Em outras palavras, uma classe só pode estender uma
outra classe Mas e se você precisar
8878 incluir algo que não pertence à classe pai? Antes do PHP 5.4 você teria que ser
criativo, mas em
8879 5.4 Traits foram introduzidos Os traços permitem basicamente "copiar e colar" uma
parte de uma classe na sua classe principal
8880 Traço Falar {
8881 /** @var string */
8882 public $frase = 'Bem Wilbur ...';
8883 função pública speak () {
8884 echo $this> frase;
8885 }
8886 }
8887 classe MrEd estende o cavalo {
8888 use o Talk;
8889 função pública __construct () {
8890 $this> speak ();
8891 }
8892 função pública setPhrase ($phrase) {
8893 $this> frase = $frase;
8894 }
8895 }
8896 Então aqui temos o MrEd, que já está estendendo o cavalo Mas nem todos os cavalos
falam, então temos uma característica para isso Vamos
8897 observe o que isso está fazendo
8898 Primeiro, definimos nossa característica Podemos usálo com autoloading e namespaces
(veja também Referenciando uma classe ou função).
8899 em um namespace) Em seguida, incluímos em nossa classe MrEd com o uso da palavrachave.
8900 Você notará que o MrEd leva a usar as funções e variáveis do Talk sem definilas
Lembrese do que nós
8901 disse sobre copiar e colar? Essas funções e variáveis são todas definidas dentro da
classe agora, como se essa classe tivesse
8902 definilos
8903 Os traços estão mais intimamente relacionados às classes abstratas, na medida em que
você pode definir variáveis e funções Você também não pode
8904 instanciar um traço diretamente (ou seja, novo Traço ()) Os traços não podem forçar
uma classe a definir implicitamente uma função como uma
8905 Classe abstrata ou uma interface pode As características são apenas para definições
explícitas (uma vez que você pode implementar quantas
8906 Interfaces como você deseja, veja Interfaces)
8907 Quando devo usar um traço?
8908 A primeira coisa que você deve fazer, ao considerar uma característica, é perguntar
a si mesmo esta importante questão
8909 Posso evitar o uso de um traço reestruturando meu código?
8910 Mais frequentemente do que não, a resposta vai ser sim As características são casos
de borda causados por herança única o
8911 tentação de uso indevido ou uso excessivo As características podem ser altas Mas
considere que uma Característica introduz outra fonte para o seu
8912 código, o que significa que há outra camada de complexidade No exemplo aqui, estamos
lidando apenas com 3 classes Mas
8913 Traços significam que agora você pode estar lidando com muito mais do que isso Para
cada traço, sua classe se torna muito mais difícil
8914 lidar, já que agora você deve fazer referência a cada Característica para descobrir
o que ela define (e potencialmente onde
8915 colisão aconteceu, veja Resolução de Conflitos) Idealmente, você deve manter o menor
número possível de características em seu código.
8916 FF
8917 Notas PHP para Profissionais 220
8918 Seção 40.2: Características para facilitar a reutilização de código horizontal
8919 Digamos que tenhamos uma interface para registro:
8920 logger de interface {
8921 log de funções ($message);
8922 }
8923 Agora digamos que temos duas implementações concretas da interface do Logger: o
FileLogger e o ConsoleLogger
8924 classe FileLogger implementa o Logger {
8925 log de função pública ($message) {
8926 //Anexa mensagem de log em algum arquivo
8927 }
8928 }
8929 classe ConsoleLogger implementa o Logger {
8930 log de função pública ($message) {
8931 //Log mensagem para o console
8932 }
8933 }
8934 Agora, se você definir alguma outra classe Foo que você também quer ser capaz de
executar tarefas de log, você poderia fazer
8935 algo assim:
8936 class Foo implementa o Logger {
8937 $logger privado;
8938 função pública setLogger (Logger $logger) {
8939 $this> logger = $logger;
8940 }
8941 log de função pública ($message) {
8942 if ($this> logger) {
8943 $this> logger> log ($mensagem);
8944 }
8945 }
8946 }
8947 Foo agora também é um registrador, mas sua funcionalidade depende da implementação
do registrador passada para ele via setLogger ()
8948 Se agora queremos que o Class Bar também tenha esse mecanismo de log, teríamos que
duplicar essa lógica no
8949 Classe de bar
8950 Em vez de duplicar o código, um traço pode ser definido:
8951 LoggableTrait {
8952 protegido $logger;
8953 função pública setLogger (Logger $logger) {
8954 $this> logger = $logger;
8955 }
8956 log de função pública ($message) {
8957 if ($this> logger) {
8958 $this> logger> log ($mensagem);
8959 }
8960 }
8961 }
8962 FF
8963 Notas PHP para Profissionais 221
8964 Agora que definimos a lógica em uma característica, podemos usar a característica
para adicionar a lógica às classes Foo e Bar:
8965 class Foo {
8966 use o LoggableTrait;
8967 }
8968 barra de classe {
8969 use o LoggableTrait;
8970 }
8971 E, por exemplo, podemos usar a classe Foo assim:
8972 $foo = new Foo ();
8973 $foo> setLogger (novo FileLogger ());
8974 //observe como usamos o trait como um 'proxy' para chamar o método de log do Logger
na instância de Foo
8975 $foo> log ('minha bela mensagem');
8976 Seção 40.3: Resolução de Conflitos
8977 Tentar usar vários traços em uma classe pode resultar em problemas envolvendo
métodos conflitantes Você precisa resolver
8978 tais conflitos manualmente
8979 Por exemplo, vamos criar essa hierarquia:
8980 traço MeowTrait {
8981 função pública say () {
8982 print "Meow \ n";
8983 }
8984 }
8985 traço WoofTrait {
8986 função pública say () {
8987 print "Woof \ n";
8988 }
8989 }
8990 classe abstrata UnMuteAnimals {
8991 função abstrata say ();
8992 }
8993 classe Dog estende UnMuteAnimals {
8994 use o WoofTrait;
8995 }
8996 classe Cat estende UnMuteAnimals {
8997 use o MeowTrait;
8998 }
8999 Agora, vamos tentar criar a seguinte classe:
9000 class TalkingParrot estende UnMuteAnimals {
9001 use MeowTrait, WoofTrait;
9002 }
9003 O interpretador do php retornará um erro fatal:
9004 FF
9005 Notas PHP para Profissionais 222
9006 Erro fatal: o método de traço não foi aplicado, porque há colisões com outros
métodos de traço
9007 em TalkingParrot
9008 Para resolver esse conflito, poderíamos fazer isso:
9009 use palavrachave insteadof para usar o método de uma característica em vez de método
de outra característica
9010 crie um alias para o método com uma construção como WoofTrait :: say as sayAsDog;
9011 class TalkingParrotV2 estende UnMuteAnimals {
9012 use MeowTrait, WoofTrait {
9013 MeowTrait :: diga em vez de WoofTrait;
9014 WoofTrait :: say as sayAsDog;
9015 }
9016 }
9017 $talkingParrot = new TalkingParrotV2 ();
9018 $talkingParrot> say ();
9019 $talkingParrot> sayAsDog ();
9020 Este código produzirá a seguinte saída:
9021 Miau
9022 Woof
9023 Seção 40.4: Implementando um singleton usando traços
9024 Disclaimer: De forma alguma este exemplo defende o uso de singletons Singletons
devem ser usados com muito cuidado.
9025 No PHP há uma maneira bastante padrão de implementar um singleton:
9026 classe pública Singleton {
9027 instância $privada;
9028 função privada __construct () {};
9029 public function getInstance () {
9030 if (! self :: $instance) {
9031 //new self () é 'basicamente' equivalente ao novo Singleton ()
9032 self :: $instance = new self ();
9033 }
9034 return self :: $instance;
9035 }
9036 //Prevenir clonagem da instância
9037 função protegida __clone () {}
9038 //Prevenir a serialização da instância
9039 função protegida __sleep () {}
9040 //Prevenir a desserialização da instância
9041 função protegida __wakeup () {}
9042 }
9043 Para evitar a duplicação de código, é uma boa ideia extrair esse comportamento em
uma característica.
9044 FF
9045 Notas PHP para Profissionais 223
9046 traço SingletonTrait {
9047 instância $privada;
9048 função protegida __construct () {};
9049 public function getInstance () {
9050 if (! self :: $instance) {
9051 //new self () se referirá à classe que usa o trait
9052 self :: $instance = new self ();
9053 }
9054 return self :: $instance;
9055 }
9056 função protegida __clone () {}
9057 função protegida __sleep () {}
9058 função protegida __wakeup () {}
9059 }
9060 Agora, qualquer classe que queira funcionar como um singleton pode simplesmente usar
a característica:
9061 class MyClass {
9062 use SingletonTrait;
9063 }
9064 //Erro! Construtor não é publicamente acessível
9065 $myClass = new MyClass ();
9066 $myClass = MyClass :: getInstance ();
9067 //Todas as chamadas abaixo falharão devido à visibilidade do método
9068 $myClassCopy = clone $myClass; //Erro!
9069 $serializedMyClass = serialize ($myClass); //Erro!
9070 $myClass = deserialize ($serializedMyclass); //Erro!
9071 Embora agora seja impossível serializar um singleton, ainda é útil não permitir o
método de desserialização
9072 Seção 40.5: Características para manter as classes limpas
9073 Com o tempo, nossas classes podem implementar mais e mais interfaces Quando essas
interfaces têm muitos métodos, o
9074 O número total de métodos em nossa classe se tornará muito grande
9075 Por exemplo, vamos supor que temos duas interfaces e uma classe implementandoas:
9076 interface imprimível {
9077 função pública print ();
9078 //outros métodos de interface .
9079 }
9080 interface Cacheable {
9081 //métodos de interface
9082 }
9083 class Artigo implementa Cachimbo, Printable {
9084 //aqui devemos implementar todos os métodos de interface
9085 Função pública print () {{
9086 /* código para imprimir o artigo */
9087 }
9088 }
9089 FF
9090 Notas PHP para Profissionais 224
9091 Em vez de implementar todos os métodos de interface dentro da classe Article,
poderíamos usar Traits separados para
9092 implementar essas interfaces, mantendo a classe menor e separando o código da
interface
9093 implementação da classe
9094 Do exemplo, para implementar a interface Printable, poderíamos criar esse traço:
9095 traço PrintableArticle {
9096 //implementa aqui os métodos de interface
9097 Função pública print () {
9098 /* código para imprimir o artigo */
9099 }
9100 }
9101 e faça a turma usar o traço:
9102 class Artigo implementa Cachimbo, Printable {
9103 use PrintableArticle;
9104 use CacheableArticle;
9105 }
9106 Os principais benefícios seriam que nossos métodos de implementação de interface
seriam separados do restante do
9107 classe, e armazenado em um traço que tem a responsabilidade exclusiva de implementar
a interface para esse tipo específico
9108 de objeto
9109 Seção 40.6: Uso de múltiplas características
9110 traço Olá {
9111 função pública sayHello () {
9112 eco 'Olá';
9113 }
9114 }
9115 traço mundo {
9116 função pública sayWorld () {
9117 eco 'mundo';
9118 }
9119 }
9120 class MyHelloWorld {
9121 use Olá, mundo;
9122 função pública sayExclamationMark () {
9123 eco '!';
9124 }
9125 }
9126 $o = new MyHelloWorld ();
9127 $o> sayHello ();
9128 $o> sayWorld ();
9129 $o> sayExclamationMark ();
9130 O exemplo acima irá gerar:
9131 Olá Mundo!
9132 Seção 40.7: Mudando a Visibilidade do Método
9133 traço HelloWorld {
9134 FF
9135 Notas PHP para Profissionais 225
9136 função pública sayHello () {
9137 eco 'Olá, mundo!';
9138 }
9139 }
9140 //Alterar a visibilidade de sayHello
9141 class MyClass1 {
9142 use HelloWorld {sayHello como protegido; }
9143 }
9144 //Método de alias com visibilidade alterada
9145 //sayHello visibility not changed
9146 class MyClass2 {
9147 use HelloWorld {sayHello como privado myPrivateHello; }
9148 }
9149 Executando este exemplo:
9150 (new MyClass1 ()) > sayHello ();
9151 //Erro fatal: Erro não detectado: Chamada para o método protegido MyClass1 ::
sayHello ()
9152 (new MyClass2 ()) > myPrivateHello ();
9153 //Erro fatal: Erro não detectado: Chamada para o método privado MyClass2 ::
myPrivateHello ()
9154 (new MyClass2 ()) > sayHello ();
9155 //Olá Mundo!
9156 Portanto, esteja ciente de que no último exemplo no MyClass2 o método original sem
suavização do traço HelloWorld permanece
9157 acessível como está.
9158 FF
9159 Notas PHP para Profissionais 226
9160 Capítulo 41: Dependência do Composer
9161 Gerente
9162 Detalhes do Parâmetro
9163 licença Define o tipo de licença que você deseja usar no projeto
9164 autores Define os autores do projeto, bem como os detalhes do autor
9165 suporte Define os emails de suporte, o canal irc e vários links
9166 require Define as dependências reais, bem como as versões do pacote
9167 requiredev Define os pacotes necessários para o desenvolvimento do projeto
9168 sugerir Define as sugestões do pacote, ou seja, pacotes que podem ajudar se
instalados
9169 autoload Define as políticas de carregamento automático do projeto
9170 autoloaddev Define as políticas de carregamento automático para o desenvolvimento do
projeto
9171 O Composer é o gerenciador de dependências mais utilizado do PHP É análogo ao npm no
Node, pip no Python ou
9172 NuGet for .NET
9173 Seção 41.1: O que é o Composer?
9174 O Composer é um gerenciador de dependências /pacotes para PHP Pode ser usado para
instalar, rastrear e atualizar seu
9175 dependências do projeto O Composer também cuida do carregamento automático das
dependências nas quais seu aplicativo depende,
9176 permitindo que você use facilmente a dependência dentro de seu projeto sem se
preocupar em incluílos no topo de qualquer
9177 dado arquivo
9178 Dependências para o seu projeto estão listadas em um arquivo composer.json que
normalmente está localizado na raiz do seu projeto
9179 Este arquivo contém informações sobre as versões necessárias dos pacotes para
produção e também desenvolvimento
9180 Um resumo completo do esquema composer.json pode ser encontrado no site do Composer
9181 Este arquivo pode ser editado manualmente usando qualquer editor de texto ou
automaticamente através da linha de comando via comandos
9182 tal como composer requer <package> ou composer requiredev <package>
9183 Para começar a usar o composer em seu projeto, você precisará criar o arquivo
composer.json Você pode criálo
9184 manualmente ou simplesmente executar o init do compositor Depois de executar o
composer init em seu terminal, ele irá pedir algumas informações básicas.
9185 informações sobre o seu projeto: Nome do pacote (fornecedor /pacote por exemplo,
laravel /laravel), Descrição opcional,
9186 Autor e algumas outras informações como Estabilidade Mínima, Licença e Pacotes
Necessários
9187 A chave require no seu arquivo composer.json especifica o Composer do qual os
pacotes do seu projeto dependem exigir
9188 pega um objeto que mapeia nomes de pacotes (por exemplo, monolog /monolog) para
restrições de versão (por exemplo, 1.0 *)
9189 {
9190 "require": {
9191 "compositor /compositor": "1.2 *"
9192 }
9193 }
9194 Para instalar as dependências definidas, você precisará executar o comando composer
install e, em seguida, localizará
9195 pacotes definidos que correspondem à restrição de versão fornecida e fazem o
download no diretório do fornecedor É um
9196 convenção para colocar código de terceiros em um diretório chamado fornecedor
9197 Você notará que o comando install também criou um arquivo composer.lock
9198 Um arquivo composer.lock é gerado automaticamente pelo Composer Este arquivo é usado
para rastrear o atualmente instalado
9199 FF
9200 Notas PHP para Profissionais 227
9201 versões e estado de suas dependências A execução da instalação do compositor
instalará os pacotes exatamente no estado
9202 armazenado no arquivo de bloqueio
9203 Seção 41.2: Carregamento automático com o Compositor
9204 Enquanto o composer fornece um sistema para gerenciar dependências para projetos PHP
(por exemplo, do Packagist), ele também pode
9205 especialmente como um autoloader, especificando onde procurar namespaces específicos
ou incluir arquivos de função genéricos
9206 Começa com o arquivo composer.json:
9207 {
9208 //.
9209 "autoload": {
9210 "psr4": {
9211 "MyVendorName \\ MyProject": "src /"
9212 }
9213 "arquivos": [
9214 "src /functions.php"
9215 ]
9216 }
9217 "autoloaddev": {
9218 "psr4": {
9219 "MyVendorName \\ MyProject \\ Tests": "tests /"
9220 }
9221 }
9222 }
9223 Esse código de configuração garante que todas as classes no namespace MyVendorName \
MyProject sejam mapeadas para o src
9224 diretório e todas as classes em MyVendorName \ MyProject \ Tests para o diretório de
testes (em relação ao seu diretório raiz) isto
9225 também incluirá automaticamente o arquivo functions.php
9226 Depois de colocar isso no seu arquivo composer.json, execute a atualização do
compositor em um terminal para que o compositor atualize o arquivo
9227 dependências, o arquivo de bloqueio e gerar o arquivo autoload.php Ao implantar em
um ambiente de produção, você
9228 usaria o composer install nodev O arquivo autoload.php pode ser encontrado no
diretório do fornecedor, que deve
9229 ser gerado no diretório onde o composer.json reside
9230 Você deve exigir este arquivo no início de um ponto de configuração no ciclo de vida
do seu aplicativo usando uma linha semelhante a essa
9231 abaixo
9232 require_once __DIR__ '/vendor/autoload.php';
9233 Uma vez incluído, o arquivo autoload.php se encarrega de carregar todas as
dependências que você forneceu
9234 arquivo composer.json
9235 Alguns exemplos do caminho de classe para o mapeamento de diretório:
9236 MyVendorName \ MyProject \ Shapes \ Square src /Shapes /Square.php.
9237 MyVendorName \ MyProject \ Tests \ Shapes \ Square testes /formas /Square.php.
9238 Seção 41.3: Diferença entre 'composer install' e
9239 'composer update'
9240 atualização do compositor
9241 A atualização do composer atualizará nossas dependências conforme elas forem
especificadas no composer.json.
9242 FF
9243 Notas PHP para Profissionais 228
9244 Por exemplo, se nosso projeto usa essa configuração:
9245 "require": {
9246 "laravelcollective /html": "2.0 *"
9247 }
9248 Supondo que tenhamos instalado a versão 2.0.1 do pacote, executar a atualização do
compositor causará uma
9249 atualização deste pacote (por exemplo para 2.0.2, se já tiver sido liberado)
9250 Em detalhe a atualização do compositor irá:
9251 Ler composer.json
9252 Remova os pacotes instalados que não são mais necessários no composer.json
9253 Verifique a disponibilidade das versões mais recentes de nossos pacotes obrigatórios
9254 Instale as versões mais recentes dos nossos pacotes
9255 Atualize composer.lock para armazenar a versão dos pacotes instalados
9256 instalação do compositor
9257 A instalação do composer instalará todas as dependências conforme especificado no
arquivo composer.lock na versão especificada
9258 (bloqueado), sem atualizar nada
9259 Em detalhe:
9260 Leia o arquivo composer.lock
9261 Instale os pacotes especificados no arquivo composer.lock
9262 Quando instalar e quando atualizar
9263 A atualização do compositor é usada principalmente na fase de 'desenvolvimento' para
atualizar nossos pacotes de projeto
9264 A instalação do composer é usada principalmente na "fase de implementação" para
instalar nosso aplicativo em um servidor de produção
9265 ou em um ambiente de teste, usando as mesmas dependências armazenadas no arquivo
composer.lock criado por
9266 atualização do compositor
9267 Seção 41.4: Comandos Disponíveis do Compositor
9268 Uso de Comando
9269 sobre Curta informação sobre o Composer
9270 arquivo Crie um arquivo deste pacote do compositor
9271 browse Abre a URL do repositório do pacote ou página inicial em seu navegador
9272 clearcache Limpa o cache do pacote interno do compositor
9273 clearcache Limpa o cache do pacote interno do compositor
9274 config Configurar opções de configuração
9275 createproject Cria novo projeto a partir de um pacote no diretório fornecido
9276 depende Mostra quais pacotes fazem com que o pacote fornecido seja instalado
9277 diagnosticar Diagnostica o sistema para identificar erros comuns
9278 dumpautoload Despeja o autoloader
9279 dumpautoload Descarrega o autoloader
9280 exec Executa um script /binário vendido
9281 global Permite executar comandos no diretório do compositor global ($COMPOSER_HOME)
9282 help Exibe ajuda para um comando
9283 home Abre a URL do repositório do pacote ou página inicial em seu navegador.
9284 FF
9285 Notas PHP para Profissionais 229
9286 info Mostrar informações sobre pacotes
9287 init Cria um arquivo composer.json básico no diretório atual
9288 install Instala as dependências do projeto do arquivo composer.lock, se presente, ou
recai sobre o
9289 composer.json
9290 licenças Mostrar informações sobre licenças de dependências
9291 lista Listas de comandos
9292 desatualizado Mostra uma lista de pacotes instalados que possuem atualizações
disponíveis, incluindo sua versão mais recente
9293 proíbe Mostra quais pacotes impedem que o pacote fornecido seja instalado
9294 remove Remove um pacote do require ou requiredev
9295 require Adiciona os pacotes necessários ao seu composer.json e os instala
9296 runscript Executa os scripts definidos no composer.json
9297 search Pesquisar por pacotes
9298 autoatualização Atualiza composer.phar para a versão mais recente
9299 selfupdate Atualiza composer.phar para a versão mais recente
9300 show Mostrar informações sobre pacotes
9301 status Mostrar uma lista de pacotes modificados localmente
9302 sugere Mostrar sugestões de pacote
9303 update Atualiza suas dependências para a versão mais recente de acordo com
composer.json e atualiza o
9304 arquivo composer.lock
9305 validate Valida um composer.json e composer.lock
9306 porque mostra quais pacotes fazem com que o pacote fornecido seja instalado
9307 por que não? Mostra quais pacotes impedem que o pacote fornecido seja instalado
9308 Seção 41.5: Benefícios do uso do Composer
9309 O Composer rastreia quais versões de pacotes você instalou em um arquivo chamado
composer.lock, que se destina a
9310 estar comprometido com o controle de versão, para que, quando o projeto for clonado
no futuro, simplesmente executar a instalação do compositor
9311 irá baixar e instalar todas as dependências do projeto
9312 O Composer lida com dependências do PHP em uma base por projeto Isso facilita ter
vários projetos em um
9313 máquina que depende de versões separadas de um pacote PHP
9314 O compositor rastreia quais dependências são destinadas apenas para ambientes dev
apenas
9315 compositor requer dev phpunit /phpunit
9316 O Composer fornece um autoloader, tornando extremamente fácil começar com qualquer
pacote Por exemplo, depois
9317 Ao instalar o Goutte com o composer, é necessário usar o fabpot /goutte Você pode
começar imediatamente a usar o Goutte em um novo projeto:
9318 <?php
9319 exigir __DIR__ '/vendor/autoload.php';
9320 $client = new Goutte \ Client ();
9321 //Comece a usar o Goutte
9322 O Composer permite que você atualize facilmente um projeto para a versão mais
recente permitida pelo seu composer.json POR EXEMPLO.
9323 composer update fabpot /goutte, ou atualizar cada uma das dependências do seu
projeto: atualização do compositor.
9324 FF
9325 Notas PHP para Profissionais 230
9326 Seção 41.6: Instalação
9327 Você pode instalar o Composer localmente, como parte de seu projeto, ou globalmente
como um executável de todo o sistema
9328 Localmente
9329 Para instalar, execute estes comandos no seu terminal
9330 php r "copy ('https://getcomposer.org/installer', 'composersetup.php');"
9331 # para verificar a validade do instalador baixado, confira aqui o SHA384:
9332 # https://composer.github.io/pubkeys.html
9333 php composersetup.php
9334 php r "unlink ('composersetup.php');"
9335 Isso fará o download de composer.phar (um arquivo PHP Archive) para o diretório
atual Agora você pode rodar o php
9336 composer.phar para usar o Composer, por exemplo
9337 php composer.phar install
9338 Globalmente
9339 Para usar o Composer globalmente, coloque o arquivo composer.phar em um diretório
que faça parte do seu PATH
9340 mv compositor.phar /usr /local /bin /compositor
9341 Agora você pode usar composer em qualquer lugar ao invés de php composer.phar, eg
9342 instalação do compositor
9343 FF
9344 Notas PHP para Profissionais 231
9345 Capítulo 42: Métodos Mágicos
9346 Seção 42.1: __call () e __callStatic ()
9347 __call () e __callStatic () são chamados quando alguém está chamando um método de
objeto inexistente em um objeto ou estático
9348 contexto
9349 classe Foo
9350 {
9351 /**
9352 * Este método será chamado quando alguém tentar invocar um método no objeto
9353 * contexto, que não existe, como:
9354 *
9355 * $foo> método ($arg, $arg1);
9356 *
9357 * Primeiro argumento conterá o nome do método (no exemplo acima será "método"),
9358 * e o segundo conterá os valores de $arg e $arg1 como uma matriz
9359 */
9360 função pública __call ($método, $argumentos)
9361 {
9362 //faça algo com essa informação aqui, como sobrecarregar
9363 //ou algo genérico
9364 //Por exemplo, digamos que estamos fazendo uma classe genérica,
9365 //que contém alguns dados e permite ao usuário obter /definir /tem via
9366 //métodos getter /setter Também vamos supor que há algum
9367 //CaseHelper que ajuda a converter o camelCase em snake_case
9368 //Também este método é simplificado, por isso não verifica se existe
9369 //é um nome válido ou
9370 $snakeName = CaseHelper :: camelToSnake ($method);
9371 //Get get /set /tem prefixo
9372 $subMethod = substr ($snakeName, 0, 3);
9373 //Solta o nome do método
9374 $propertyName = substr ($snakeName, 4);
9375 switch ($subMethod) {
9376 caso "get":
9377 return $this> data [$propertyName];
9378 caso "set":
9379 $this> data [$propertyName] = $argumentos [0];
9380 pausa;
9381 case "has":
9382 retornar isset ($this> data [$propertyName]);
9383 padrão:
9384 throw new BadMethodCallException ("Método indefinido $método");
9385 }
9386 }
9387 /**
9388 * __callStatic será chamado do conteúdo estático, ou seja, ao chamar um não existente
9389 * método estático:
9390 *
9391 * Foo :: buildSomethingCool ($arg);
9392 *
9393 * O primeiro argumento conterá o nome do método (no exemplo acima, será
"buildSomethingCool"),
9394 * e o segundo conterá o valor $arg em um array
9395 *
9396 * Observe que a assinatura deste método é diferente (requer palavrachave estática)
Este método não foi
9397 * disponível antes do PHP 5.3
9398 */
9399 FF
9400 Notas PHP para Profissionais 232
9401 função estática pública __callStatic ($method, $arguments)
9402 {
9403 //Esse método pode ser usado quando você precisa de algo como fábrica genérica
9404 //ou outra coisa (para ser honesto, use isso para isso não é tão claro para mim)
9405 print_r (func_get_args ());
9406 }
9407 }
9408 Exemplo:
9409 $instance = new Foo ();
9410 $instance> setSomeState ("foo");
9411 var_dump ($instance> hasSomeState ()); //bool (true)
9412 var_dump ($instance> getSomeState ()); //string "foo"
9413 Foo :: exampleStaticCall ("teste");
9414 //saídas:
9415 Matriz
9416 (
9417 [0] => exampleCallStatic
9418 [1] => teste
9419 )
9420 Seção 42.2: __get (), __set (), __isset () e __unset ()
9421 Sempre que você tentar recuperar um determinado campo de uma classe da seguinte
forma:
9422 $animal = novo Animal ();
9423 $height = $animal> height;
9424 O PHP invoca o método mágico __get ($name), com $name igual a "height" neste caso
Escrevendo para um campo de classe como
9425 assim:
9426 $animal> altura = 10;
9427 Invocará o método mágico __set ($name, $value), com $name igual a "height" e $value
igual a 10
9428 O PHP também possui duas funções embutidas, isset (), que verifica se existe uma
variável, e unset (), que destrói uma variável
9429 Verificando se um campo de objetos é definido assim:
9430 isset ($animal> altura);
9431 Invocará a função __isset ($name) nesse objeto Destruindo uma variável assim:
9432 unset ($animal> altura);
9433 Invocará a função __unset ($name) nesse objeto
9434 Normalmente, quando você não define esses métodos em sua classe, o PHP apenas
recupera o campo como ele é armazenado em sua classe
9435 classe No entanto, você pode substituir esses métodos para criar classes que possam
conter dados como uma matriz, mas que sejam utilizáveis
9436 como um objeto:
9437 class Example {
9438 private $data = [];
9439 função pública __set ($name, $value) {
9440 FF
9441 Notas PHP para Profissionais 233
9442 $this> data [$name] = $valor;
9443 }
9444 função pública __get ($name) {
9445 if (! array_key_exists ($name, $this> dados)) {
9446 return null;
9447 }
9448 return $this> data [$nome];
9449 }
9450 função pública __isset ($name) {
9451 return isset ($this> dados [$nome]);
9452 }
9453 função pública __unset ($name) {
9454 unset ($this> data [$nome]);
9455 }
9456 }
9457 $example = new Exemplo ();
9458 //Armazena 'a' na matriz $data com valor 15
9459 $example> a = 15;
9460 //Recupera a chave de array 'a' do array $data
9461 echo $example> a; //imprime 15
9462 //Tentativa de recuperar chave inexistente da matriz retorna nulo
9463 echo $example> b; //imprime nada
9464 //Se __isset ('a') retornar verdadeiro, então chame __unset ('a')
9465 if (isset ($example> a)) {
9466 unset ($example> a));
9467 }
9468 função empty () e métodos mágicos
9469 Note que chamar empty () em um atributo de classe invocará __isset () porque como o
manual do PHP declara:
9470 empty () é essencialmente o equivalente conciso a! isset ($var) || $var == false
9471 Seção 42.3: __construct () e __destruct ()
9472 __construct () é o método mágico mais comum no PHP, porque é usado para configurar
uma classe quando ela é inicializada
9473 O oposto do método __construct () é o método __destruct () Este método é chamado
quando não há
9474 mais referências a um objeto que você criou ou ao forçar sua exclusão A coleta de
lixo do PHP irá limpar
9475 o objeto chamando primeiro seu destruidor e, em seguida, removendoo da memória
9476 class Shape {
9477 função pública __construct () {
9478 echo "Forma criada! \ n";
9479 }
9480 }
9481 retângulo de classe estende a forma {
9482 largura $pública;
9483 altura $pública;
9484 FF
9485 Notas PHP para Profissionais 234
9486 função pública __construct ($width, $height) {
9487 parent :: __ construct ();
9488 $this> width = $width;
9489 $this> height = $height;
9490 echo "Criada {$this> width} x {$this> height} Retângulo \ n";
9491 }
9492 função pública __destruct () {
9493 echo "Destruindo {$this> width} x {$this> height} Retângulo \ n";
9494 }
9495 }
9496 function createRectangle () {
9497 //A instanciação de um objeto chama o construtor com os argumentos especificados
9498 $retângulo = novo Retângulo (20, 50);
9499 //'Shape Created' será impresso
9500 //'Retângulo 20x50 criado' será impresso
9501 }
9502 createRectangle ();
9503 //'Destruindo 20x50 retângulo' será impresso, porque
9504 //o objeto `$rectangle` era local para a função createRectangle, então
9505 //Quando o escopo da função é encerrado, o objeto é destruído e sua
9506 //o destrutor é chamado
9507 //O destruidor de um objeto também é chamado quando não configurado é usado:
9508 unset (novo retângulo (20, 50));
9509 Seção 42.4: __toString ()
9510 Sempre que um objeto é tratado como uma string, o método __toString () é chamado
Este método deve retornar uma string
9511 representação da classe
9512 class User {
9513 public $first_name;
9514 public $last_name;
9515 público $age;
9516 função pública __toString () {
9517 return "{$this> first_name} {$this> last_name} ($this> age)";
9518 }
9519 }
9520 $user = new Usuário ();
9521 $user> first_name = "Chuck";
9522 $user> last_name = "Norris";
9523 $user> age = 76;
9524 //Sempre que o objeto $user é usado em um contexto de string, __toString () é chamado
9525 echo $user; //imprime Chuck Norris (76)
9526 //Valor da string se torna: 'Usuário selecionado: Chuck Norris (76)'
9527 $selected_user_string = sprintf ("Usuário selecionado:% s", $user);
9528 //Casting para string também chama __toString ()
9529 $user_as_string = (string) $usuário;
9530 FF
9531 Notas PHP para Profissionais 235
9532 Seção 42.5: __clone ()
9533 __clone é invocado pelo uso da palavrachave clone Ele é usado para manipular o
estado do objeto após a clonagem, após o objeto
9534 foi realmente clonado
9535 class CloneableUser
9536 {
9537 nome $público;
9538 public $lastName;
9539 /**
9540 * Esse método será invocado por um operador clone e será precedido de "Copiar" para o
9541 * propriedades name e lastName
9542 */
9543 função pública __clone ()
9544 {
9545 $this> name = "Copiar" $this> name;
9546 $this> lastName = "Copiar" $this> lastName;
9547 }
9548 }
9549 Exemplo:
9550 $user1 = new CloneableUser ();
9551 $user1> name = "John";
9552 $user1> lastName = "Doe";
9553 $user2 = clone $user1; //aciona o método mágico __clone
9554 echo $user2> nome; //Copiar John
9555 echo $user2> lastName; //Copiar Doe
9556 Seção 42.6: __invoke ()
9557 Esse método mágico é chamado quando o usuário tenta invocar o objeto como uma função
Casos de uso possíveis podem incluir alguns
9558 abordagens como programação funcional ou alguns retornos de chamada
9559 classe Invokable
9560 {
9561 /**
9562 * Este método será chamado se o objeto for executado como uma função:
9563 *
9564 * $invokable ();
9565 *
9566 * Args será passado como na chamada de método regular
9567 */
9568 função pública __invoke ($arg, $arg, ...)
9569 {
9570 print_r (func_get_args ());
9571 }
9572 }
9573 //Exemplo:
9574 $invokable = new Invokable ();
9575 $invokable ([1, 2, 3]);
9576 //optputs:
9577 Matriz
9578 (
9579 FF
9580 Notas PHP para Profissionais 236
9581 [0] => 1
9582 [1] => 2
9583 [2] => 3
9584 )
9585 Seção 42.7: __sleep () e __wakeup ()
9586 __sleep e __wakeup são métodos relacionados ao processo de serialização função
serializar verifica se um
9587 A classe tem um método __sleep Em caso afirmativo, será executado antes de qualquer
serialização __sleep deve retornar um
9588 array dos nomes de todas as variáveis de um objeto que deve ser serializado
9589 __wakeup por sua vez será executado por unserialize se estiver presente na classe
Sua intenção é restabelecer recursos
9590 e outras coisas que precisam ser inicializadas após a desserialização
9591 class Sleepy {
9592 public $tableName;
9593 public $tableFields;
9594 public $dbConnection;
9595 /**
9596 * Este método mágico será invocado pela função serializar
9597 * Observe que $dbConnection está excluído
9598 */
9599 função pública __sleep ()
9600 {
9601 //Somente $this> tableName e $this> tableFields serão serializados
9602 return ['tableName', 'tableFields'];
9603 }
9604 /**
9605 * Este método mágico será chamado pela função unserialize
9606 *
9607 * Por exemplo, vamos supor que $this> c, que não foi serializado,
9608 * é algum tipo de conexão de banco de dados Então, ao acordar, ele será reconectado.
9609 */
9610 função pública __wakeup ()
9611 {
9612 //Conectase a algum banco de dados padrão e armazena o manipulador /wrapper retornado
9613 //$this> dbConnection
9614 $this> dbConnection = DB :: connect ();
9615 }
9616 }
9617 Seção 42.8: __debugInfo ()
9618 Esse método é chamado por var_dump () ao despejar um objeto para obter as
propriedades que devem ser mostradas
9619 Se o método não estiver definido em um objeto, todas as propriedades públicas,
protegidas e privadas serão mostradas
9620 Manual do PHP
9621 classe DeepThought {
9622 função pública __debugInfo () {
9623 retorno [42];
9624 }
9625 }
9626 Versão = 5,6
9627 var_dump (new DeepThought ());
9628 FF
9629 Notas PHP para Profissionais 237
9630 O exemplo acima irá gerar:
9631 classe DeepThought # 1 (0) {
9632 }
9633 Versão = 5,6
9634 var_dump (new DeepThought ());
9635 O exemplo acima irá gerar:
9636 classe DeepThought # 1 (1) {
9637 public ${0} =>
9638 int (42)
9639 }
9640 FF
9641 Notas PHP para Profissionais 238
9642 Capítulo 43: Manipulação de arquivos
9643 Parâmetro Descrição
9644 filename O nome do arquivo sendo lido
9645 use_include_path Você pode usar o segundo parâmetro opcional e configurálo para
TRUE, se você quiser procurar o arquivo
9646 no include_path também
9647 contexto Um recurso de fluxo de contexto
9648 Seção 43.1: Funções de conveniência
9649 Raw IO direto
9650 file_get_contents e file_put_contents fornecem a capacidade de ler /escrever de
/para um arquivo de /para uma string PHP em um
9651 chamada única
9652 file_put_contents também pode ser usado com o sinalizador de bitmask FILE_APPEND
para anexar, em vez de truncar e
9653 sobrescrever, o arquivo Ele pode ser usado junto com o bitmask LOCK_EX para adquirir
um bloqueio exclusivo para o arquivo enquanto
9654 continuando a escrever Sinalizadores Bitmask podem ser associados ao | operador bit
a bit OR.
9655 $path = "file.txt";
9656 //lê o conteúdo em file.txt para $contents
9657 $contents = file_get_contents ($caminho);
9658 //vamos mudar alguma coisa .por exemplo, converter o CRLF para LF!
9659 $contents = str_replace ("\ r \ n", "\ n", $conteúdo);
9660 //agora escreva de volta no arquivo.txt, substituindo o conteúdo original
9661 file_put_contents ($path, $contents);
9662 FILE_APPEND é útil para anexar arquivos de log enquanto o LOCK_EX ajuda a evitar que
a condição de corrida da gravação de arquivos seja
9663 vários processos Por exemplo, para gravar em um arquivo de log sobre a sessão atual:
9664 file_put_contents ("logins.log", "{$_SESSION [" username "]} logado", FILE_APPEND |
LOCK_EX);
9665 CSV IO
9666 fgetcsv ($file, $length, $separator)
9667 O fgetcsv analisa a linha da verificação de arquivos abertos para campos csv Ele
retorna campos CSV em uma matriz com sucesso ou FALSE
9668 no fracasso
9669 Por padrão, ele lerá apenas uma linha do arquivo CSV
9670 $file = fopen ("contacts.csv", "r");
9671 print_r (fgetcsv ($file));
9672 print_r (fgetcsv ($arquivo, 5, ""));
9673 fclose ($file);
9674 contacts.csv
9675 Kai Jim, Refnes, Stavanger, Noruega
9676 Hege, Refsnes, Stavanger, Noruega
9677 Saída:
9678 Matriz
9679 (
9680 [0] => Kai Jim
9681 FF
9682 Notas PHP para Profissionais 239
9683 [1] => Refsnes
9684 [2] => Stavanger
9685 [3] => Noruega
9686 )
9687 Matriz
9688 (
9689 [0] => Hege,
9690 )
9691 Lendo um arquivo para stdout diretamente
9692 readfile copia um arquivo para o buffer de saída readfile () não apresentará
problemas de memória, mesmo ao enviar grandes
9693 arquivos, por conta própria
9694 $file = 'monkey.gif';
9695 if (file_exists ($file)) {
9696 cabeçalho ('Descrição do conteúdo: Transferência de arquivos');
9697 header ('ContentType: application /octetstream');
9698 header ('ContentDisposition: anexo; nome do arquivo = "' basename ($file) '"');
9699 cabeçalho ('Expira: 0');
9700 cabeçalho ('CacheControl: mustrevalidate');
9701 cabeçalho ('Pragma: public');
9702 cabeçalho ('ContentLength:' filesize ($file));
9703 readfile ($file);
9704 Saída;
9705 }
9706 Ou de um ponteiro de arquivo
9707 Como alternativa, para procurar um ponto no arquivo para iniciar a cópia para
stdout, use fpassthru No exemplo a seguir,
9708 os últimos 1024 bytes são copiados para stdout:
9709 $fh = fopen ("file.txt", "rb");
9710 fseek ($fh, 1024, SEEK_END);
9711 fpassthru ($fh);
9712 Lendo um arquivo em uma matriz
9713 arquivo retorna as linhas no arquivo passado em uma matriz Cada elemento da matriz
corresponde a uma linha no arquivo, com
9714 a nova linha ainda está anexada
9715 print_r (arquivo ("test.txt"));
9716 test.txt
9717 Bemvindo ao manuseio de arquivos
9718 Isso é para testar o manuseio de arquivos
9719 Saída:
9720 Matriz
9721 (
9722 [0] => Bemvindo ao manuseio de arquivos
9723 [1] => Isso é para testar o tratamento de arquivos
9724 )
9725 FF
9726 Notas PHP para Profissionais 240
9727 Seção 43.2: Excluindo arquivos e diretórios
9728 Excluindo arquivos
9729 A função de desconexão exclui um único arquivo e retorna se a operação foi
bemsucedida
9730 $filename = '/caminho /para /arquivo.txt';
9731 if (file_exists ($filename)) {
9732 $success = unlink ($filename);
9733 if (! $success) {
9734 throw new Exception ("Não é possível excluir $filename");
9735 }
9736 }
9737 Excluindo diretórios, com exclusão recursiva
9738 Por outro lado, os diretórios devem ser excluídos com rmdir No entanto, essa função
apenas exclui diretórios vazios.
9739 Para excluir um diretório com arquivos, exclua os arquivos nos diretórios primeiro
Se o diretório contiver subdiretórios,
9740 recursão pode ser necessária
9741 O exemplo a seguir verifica arquivos em um diretório, exclui arquivos /diretórios de
membros recursivamente e retorna
9742 número de arquivos (não diretórios) excluídos
9743 função recurse_delete_dir (string $dir): int {
9744 $count = 0;
9745 //certifiquese de que $dir termine com uma barra para que possamos concatenalo
diretamente com os nomes dos arquivos
9746 $dir = rtrim ($dir, "/\\") "/";
9747 //use dir () para listar arquivos
9748 $list = dir ($dir);
9749 //armazena o próximo nome do arquivo em $file se $file é falso, é tudo termine o
loop.
9750 while (($file = $list> read ())! == false) {
9751 if ($file === "." || $file === "..") continuar;
9752 if (is_file ($dir $file)) {
9753 unlink ($dir $arquivo);
9754 $count ++;
9755 } elseif (is_dir ($dir $file)) {
9756 $count + = recurse_delete_dir ($dir $file);
9757 }
9758 }
9759 //finalmente, seguro excluir o diretório!
9760 rmdir ($dir);
9761 devolve $count;
9762 }
9763 Seção 43.3: Obtendo informações sobre o arquivo
9764 Verifique se um caminho é um diretório ou um arquivo
9765 A função is_dir retorna se o argumento é um diretório, enquanto is_file retorna se o
argumento é um
9766 Arquivo Use file_exists para verificar se também é.
9767 $dir = "/this /is /a /directory";
9768 FF
9769 Notas PHP para Profissionais 241
9770 $file = "/this/is/a/file.txt";
9771 echo is_dir ($dir)? "$dir é um diretório": "$dir não é um diretório", PHP_EOL,
9772 is_file ($dir)? "$dir é um arquivo": "$dir não é um arquivo", PHP_EOL,
9773 file_exists ($dir)? "$dir existe": "$dir não existe", PHP_EOL,
9774 is_dir ($file)? "$file é um diretório": "$file não é um diretório", PHP_EOL,
9775 is_file ($file)? "$file é um arquivo": "$file não é um arquivo", PHP_EOL,
9776 file_exists ($file)? "$arquivo existe": "$arquivo não existe", PHP_EOL;
9777 Isto dá:
9778 /this /is /a /directory é um diretório
9779 /this /is /a /directory não é um arquivo
9780 /this /is /a /directory existe
9781 /this/is/a/file.txt não é um diretório
9782 /this/is/a/file.txt é um arquivo
9783 /this/is/a/file.txt existe
9784 Verificando o tipo de arquivo
9785 Use o tipo de arquivo para verificar o tipo de um arquivo, que pode ser:
9786 fifo
9787 Caracteres
9788 dir
9789 quadra
9790 ligação
9791 Arquivo
9792 soquete
9793 desconhecido
9794 Passando o nome do arquivo para o tipo de arquivo diretamente:
9795 tipo de arquivo de eco ("~"); //dir
9796 Observe que o tipo de arquivo retorna false e aciona um E_WARNING se o arquivo não
existir
9797 Verificação da legibilidade e capacidade de escrita
9798 Passando o nome do arquivo para as funções is_writable e is_readable, verifique se o
arquivo é gravável ou legível
9799 respectivamente
9800 As funções retornam false graciosamente se o arquivo não existir
9801 Verificando o acesso ao arquivo /modificar tempo
9802 Usando filemtime e fileatime retorna o timestamp da última modificação ou acesso do
arquivo O retorno
9803 valor é um registro de data e hora Unix consulte Trabalhando com datas e hora para
obter detalhes
9804 echo "O arquivo foi modificado pela última vez em" date ("Ymd", filemtime
("file.txt"));
9805 echo "O arquivo foi acessado pela última vez em" date ("Ymd", fileatime ("file.txt"));
9806 Obter peças de caminho com fileinfo
9807 $fileToAnalyze = ('/var/www/image.png');
9808 $filePathParts = pathinfo ($fileToAnalyze);
9809 FF
9810 Notas PHP para Profissionais 242
9811 echo '<pre>';
9812 print_r ($filePathParts);
9813 eco '</pre>';
9814 Este exemplo irá gerar:
9815 Matriz
9816 (
9817 [dirname] => /var /www
9818 [basename] => image.png
9819 [extensão] => png
9820 [nome do arquivo] => imagem
9821 )
9822 Que pode ser usado como:
9823 $filePathParts ['dirname']
9824 $filePathParts ['basename']
9825 $filePathParts ['extension']
9826 $filePathParts ['nome do arquivo']
9827 Detalhes do Parâmetro
9828 $path O caminho completo do arquivo a ser analisado
9829 $option Uma das quatro opções disponíveis [PATHINFO_DIRNAME, PATHINFO_BASENAME,
PATHINFO_EXTENSION ou
9830 PATHINFO_FILENAME]
9831 Se uma opção (o segundo parâmetro) não é passada, um array associativo é retornado,
caso contrário, uma string é
9832 retornou
9833 Não valida que o arquivo existe
9834 Simplesmente analisa a string em partes Nenhuma validação é feita no arquivo
(nenhuma verificação do tipo MIME, etc.)
9835 A extensão é simplesmente a última extensão de $path O caminho para o arquivo
image.jpg.png seria .png mesmo se
9836 tecnicamente um arquivo .jpg Um arquivo sem uma extensão não retornará um elemento
de extensão na matriz.
9837 Seção 43.4: IO do arquivo baseado em fluxo
9838 Abrindo um fluxo
9839 fopen abre um identificador de fluxo de arquivos, que pode ser usado com várias
funções para leitura, escrita, busca e outras
9840 funções em cima dele Esse valor é do tipo de recurso e não pode ser passado para
outros encadeamentos que persistem
9841 funcionalidade
9842 $f = fopen ("errors.log", "a"); //Tentará abrir o errors.log para escrever
9843 O segundo parâmetro é o modo do fluxo de arquivos:
9844 Descrição do modo
9845 r Abra no modo somente leitura, começando no início do arquivo
9846 r + Aberto para leitura e escrita, começando no início do arquivo
9847 w aberto apenas para gravação, começando no início do arquivo Se o arquivo existir,
ele irá esvaziar o arquivo Se isso não acontecer
9848 Se existir, tentará criálo
9849 w + aberto para leitura e escrita, iniciando no início do arquivo Se o arquivo
existir, ele irá esvaziar o arquivo Se isso
9850 não existe, tentará criálo
9851 Abra um arquivo somente para gravação, começando no final do arquivo Se o arquivo
não existir, ele tentará criálo
9852 a + abre um arquivo para leitura e escrita, iniciando no final do arquivo Se o
arquivo não existir, ele tentará criar
9853 isto
9854 FF
9855 Notas PHP para Profissionais 243
9856 x crie e abra um arquivo apenas para gravação Se o arquivo existir, a chamada de
fopen falhará
9857 x + crie e abra um arquivo para leitura e escrita Se o arquivo existir, a chamada de
fopen falhará
9858 c abra o arquivo apenas para gravação Se o arquivo não existir, ele tentará criálo
Ele vai começar a escrever no
9859 início do arquivo, mas não irá esvaziar o arquivo antes de escrever
9860 c + abra o arquivo para ler e escrever Se o arquivo não existir, ele tentará criálo
Ele vai começar a escrever no
9861 início do arquivo, mas não irá esvaziar o arquivo antes de escrever
9862 Adicionar por trás do modo (por exemplo, um + b, wt, etc.) no Windows irá traduzir
"\ n" finais de linha para "\ r \ n" ao trabalhar
9863 com o arquivo Adicione b atrás do modo se isso não for intencional, especialmente se
for um arquivo binário.
9864 O aplicativo PHP deve fechar fluxos usando o fclose quando eles não forem mais usados
para impedir que
9865 Erro de arquivos abertos Isto é particularmente importante nos programas CLI, uma
vez que os fluxos só são fechados quando
9866 o tempo de execução é encerrado isso significa que em servidores da Web, pode não
ser necessário (mas ainda deve, como uma prática para
9867 impedir o vazamento de recursos) para fechar os fluxos se você não espera que o
processo seja executado por um longo período e não
9868 abra muitos fluxos
9869 Leitura
9870 O uso do fread lerá o número de bytes fornecido do ponteiro do arquivo ou até que um
EOF seja atendido
9871 Linhas de leitura
9872 O uso de fgets lerá o arquivo até que um EOL seja atingido ou o comprimento
determinado seja lido
9873 Tanto fread e fgets irá mover o ponteiro do arquivo durante a leitura
9874 Lendo tudo o restante
9875 Usando stream_get_contents todos os bytes restantes no fluxo em uma string e
retornálo
9876 Ajustando a posição do ponteiro do arquivo
9877 Inicialmente, após abrir o fluxo, o ponteiro do arquivo está no início do arquivo
(ou no final, se o modo a for usado)
9878 Usando a função fseek, o ponteiro do arquivo será movido para uma nova posição, em
relação a um dos três valores:
9879 SEEK_SET: este é o valor padrão; o deslocamento da posição do arquivo será relativo
ao início do arquivo.
9880 SEEK_CUR: O deslocamento da posição do arquivo será relativo à posição atual
9881 SEEK_END: O deslocamento da posição do arquivo será relativo ao final do arquivo
Passar um offset negativo é o mais
9882 uso comum para este valor; ele irá mover a posição do arquivo para o número
especificado de bytes antes do final de
9883 Arquivo
9884 rewind é um atalho de conveniência do fseek ($fh, 0, SEEK_SET)
9885 Usando ftell mostrará a posição absoluta do ponteiro do arquivo
9886 Por exemplo, o script a seguir lê ignora os primeiros 10 bytes, lê os próximos 10
bytes, ignora 10 bytes, lê o
9887 próximos 10 bytes e, em seguida, os últimos 10 bytes no arquivo.txt:
9888 $fh = fopen ("file.txt", "rb");
9889 fseek ($fh, 10); //começa no deslocamento 10
9890 eco fread ($fh, 10); //lê 10 bytes
9891 fseek ($fh, 10, SEEK_CUR); //pular 10 bytes
9892 eco fread ($fh, 10); //leia 10 bytes
9893 fseek ($fh, 10, SEEK_END); //pula para 10 bytes antes do EOF
9894 eco fread ($fh, 10); //leia 10 bytes
9895 FF
9896 Notas PHP para Profissionais 244
9897 fclose ($fh);
9898 Escrita
9899 Usando fwrite grava a string fornecida no arquivo, iniciando no ponteiro de arquivo
atual
9900 fwrite ($fh, "Algum texto aqui \ n");
9901 Seção 43.5: Movendo e copiando arquivos e diretórios
9902 Copiando arquivos
9903 copiar copia o arquivo de origem no primeiro argumento para o destino no segundo
argumento O resolvido
9904 destino precisa estar em um diretório que já está criado
9905 if (copy ('test.txt', 'dest.txt')) {
9906 echo 'O arquivo foi copiado com sucesso';
9907 } outro {
9908 echo 'Falha ao copiar arquivo para o destino fornecido.'
9909 }
9910 Copiando diretórios, com recursão
9911 Copiar diretórios é muito semelhante à exclusão de diretórios, exceto que para
copiar arquivos em vez de desvincular é usado,
9912 enquanto para diretórios, mkdir em vez de rmdir é usado, no início, em vez de estar
no final da função
9913 função recurse_delete_dir (string $src, string $dest): int {
9914 $count = 0;
9915 //assegurese de que $src e $dest terminem com uma barra para que possamos
concatenálo com os nomes dos arquivos
9916 diretamente
9917 $src = rtrim ($dest, "/\\") "/";
9918 $dest = rtrim ($dest, "/\\") "/";
9919 //use dir () para listar arquivos
9920 $list = dir ($src);
9921 //cria $dest se ainda não existe
9922 @mkdir ($dest);
9923 //armazena o próximo nome do arquivo em $file se $file é falso, é tudo termine o
loop.
9924 while (($file = $list> read ())! == false) {
9925 if ($file === "." || $file === "..") continuar;
9926 if (is_file ($src $file)) {
9927 cópia ($src $file, $dest $file);
9928 $count ++;
9929 } elseif (is_dir ($src $file)) {
9930 $count + = recurse_copy_dir ($src $file, $dest $file);
9931 }
9932 }
9933 devolve $count;
9934 }
9935 Renomeando /Movendo
9936 Renomear /mover arquivos e diretórios é muito mais simples Diretórios inteiros podem
ser movidos ou renomeados em uma única chamada,
9937 usando a função renomear
9938 renomear ("~ /arquivo.txt", "~ /arquivo.html");
9939 FF
9940 Notas PHP para Profissionais 245
9941 renomear ("~ /dir", "~ /old_dir");
9942 renomear ("~ /dir /file.txt", "~ /dir2 /file.txt");
9943 Seção 43.6: Minimize o uso da memória ao lidar com grandes
9944 arquivos
9945 Se precisarmos analisar um arquivo grande, por exemplo, um CSV com mais de 10 Mbytes
contendo milhões de linhas, alguns usam o arquivo ou
9946 funções file_get_contents e acabam atingindo a configuração memory_limit com
9947 Tamanho de memória permitido de XXXXX bytes esgotado
9948 erro Considere a seguinte fonte (top1m.csv tem exatamente 1 milhão de linhas e cerca
de 22 Mbytes de tamanho)
9949 var_dump (memory_get_usage (true));
9950 $arr = file ('top1m.csv');
9951 var_dump (memory_get_usage (true));
9952 Isso gera:
9953 int (262144)
9954 int (210501632)
9955 porque o interpretador precisava manter todas as linhas no array $arr, então
consumia ~ 200 Mbytes de RAM Observe que
9956 nós nem fizemos nada com o conteúdo do array
9957 Agora considere o seguinte código:
9958 var_dump (memory_get_usage (true));
9959 $index = 1;
9960 if (($handle = fopen ("top1m.csv", "r"))! == FALSE) {
9961 while (($row = fgetcsv ($identificador, 1000, ","))! == FALSE) {
9962 file_put_contents ('top1minvertido.csv', $index ',' strrev ($row [1]) PHP_EOL,
9963 FILE_APPEND);
9964 $index ++;
9965 }
9966 fclose ($handle);
9967 }
9968 var_dump (memory_get_usage (true));
9969 quais saídas
9970 int (262144)
9971 int (262144)
9972 por isso não usamos um único byte extra de memória, mas analisamos o CSV inteiro e o
salvamos em outro arquivo, invertendo o
9973 valor da segunda coluna Isso porque fgetcsv lê apenas uma linha e $row é sobrescrita
em cada loop.
9974 FF
9975 Notas PHP para Profissionais 246
9976 Capítulo 44: Fluxos
9977 Nome do Parâmetro Descrição
9978 Recurso de Fluxo O provedor de dados que consiste na sintaxe <scheme>: //<target>
9979 Seção 44.1: Registrando um wrapper de fluxo
9980 Um wrapper de fluxo fornece um manipulador para um ou mais esquemas específicos
9981 O exemplo abaixo mostra um wrapper de fluxo simples que envia solicitações HTTP
PATCH quando o fluxo é fechado
9982 //registra a classe FooWrapper como um wrapper para URLs foo: //
9983 stream_wrapper_register ("foo", FooWrapper :: class, STREAM_IS_URL) ou die ("wrapper
de fluxo duplicado
9984 registrado");
9985 class FooWrapper {
9986 //isso será modificado pelo PHP para mostrar o contexto passado na chamada atual
9987 contexto público $;
9988 //isto é usado neste exemplo internamente para armazenar o URL
9989 private $url;
9990 //quando fopen () com um protocolo para este wrapper é chamado, este método pode ser
implementado para
9991 armazenar dados como o host
9992 função pública stream_open (string $caminho, string $modo, int $opções, string &
$openPath):
9993 bool {
9994 $url = parse_url ($caminho);
9995 if ($url === false) retorna falso;
9996 $this> url = $url ["host"] "/" $url ["caminho"];
9997 retorno verdadeiro;
9998 }
9999 //lida com chamadas para fwrite () neste fluxo
10000 função pública stream_write (string $data): int {
10001 $this> buffer = $dados;
10002 return strlen ($data);
10003 }
10004 //lida com chamadas para fclose () neste fluxo
10005 função pública stream_close () {
10006 $curl = curl_init ("http: //" $this> url);
10007 curl_setopt ($curl, CURLOPT_POSTFIELDS, $this> buffer);
10008 curl_setopt ($curl, CURLOPT_CUSTOMREQUEST, "PATCH");
10009 curl_exec ($curl);
10010 curl_close ($curl);
10011 $this> buffer = "";
10012 }
10013 //manipulador de exceção de fallback se uma operação não suportada for tentada
10014 //isso não é necessário
10015 função pública __call ($name, $args) {
10016 throw new \ RuntimeException ("Este wrapper não suporta $name");
10017 }
10018 //isso é chamado quando unlink ("foo: //somethingelse") é chamado
10019 função pública unlink (string $caminho) {
10020 $url = parse_url ($caminho);
10021 $curl = curl_init ("http: //" $url ["host"] "/" $url ["caminho"]);
10022 curl_setopt ($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
10023 FF
10024 Notas PHP para Profissionais 247
10025 curl_exec ($curl);
10026 curl_close ($curl);
10027 }
10028 }
10029 Este exemplo mostra apenas alguns exemplos do que um wrapper de fluxo genérico
conteria Estes não são todos
10030 métodos disponíveis Uma lista completa dos métodos que podem ser implementados pode
ser encontrada em http://php.net/streamWrapper.
10031 FF
10032 Notas PHP para Profissionais 248
10033 Capítulo 45: Sugestão de Tipo
10034 Seção 45.1: Classes e interfaces de dicas de tipos
10035 A sugestão de tipos para classes e interfaces foi adicionada no PHP 5
10036 Dica de tipo de classe
10037 <?php
10038 aluno de classe
10039 {
10040 public $name = 'Chris';
10041 }
10042 Escola de turma
10043 {
10044 public $name = 'Universidade de Edimburgo';
10045 }
10046 função de inscrição (estudante $estudante, escola $escola)
10047 {
10048 echo $student> name 'está sendo registrado em' $school> name;
10049 }
10050 $estudante = novo aluno ();
10051 $school = new School ();
10052 inscrevase ($student, $school);
10053 O script acima gera:
10054 Chris está sendo matriculado na Universidade de Edimburgo
10055 Dica do tipo de interface
10056 <?php
10057 interface Inscrito {};
10058 interface Attendable {};
10059 classe Chris implementa Inscrito
10060 {
10061 public $name = 'Chris';
10062 }
10063 classe UniversityOfEdinburgh implementa Attendable
10064 {
10065 public $name = 'Universidade de Edimburgo';
10066 }
10067 function enroll (Registrável $enrollee, Attendedable $premises)
10068 {
10069 echo $enrollee> nome 'está sendo registrado em' $premissas> nome;
10070 }
10071 $chris = new Chris ();
10072 $edinburgh = new UniversityOfEdinburgh ();
10073 FF
10074 Notas PHP para Profissionais 249
10075 inscreverse ($chris, $edimburgo);
10076 O exemplo acima gera o mesmo de antes:
10077 Chris está sendo matriculado na Universidade de Edimburgo
10078 Dicas de auto tipo
10079 A palavrachave self pode ser usada como uma dica de tipo para indicar que o valor
deve ser uma instância da classe que
10080 declara o método
10081 Seção 45.2: Tipos escalares de dica de tipos, matrizes e callables
10082 Suporte para parâmetros de matriz de insinuações de tipos (e valores de retorno após
o PHP 7.1) foi adicionado no PHP 5.1 com a palavrachave
10083 array Quaisquer matrizes de quaisquer dimensões e tipos, bem como matrizes vazias,
são valores válidos.
10084 Suporte para callables de hintagem de tipos foi adicionado no PHP 5.4 Qualquer valor
que é valido () é válido para parâmetros e
10085 valores de retorno sugeridos chamavel, ou seja, objetos de fechamento, strings de
nome de funcao e array (class_name | object,
10086 method_name)
10087 Se um erro de digitação ocorrer no nome da função, de modo que não seja is_callable
(), uma mensagem de erro menos óbvia seria
10088 exibido:
10089 Erro fatal: Uncaught TypeError: O argumento 1 passado para foo () deve ser do tipo
que pode ser chamado, string /array
10090 dado
10091 função foo (callable $c) {}
10092 foo ("contar"); //válido
10093 foo ("Phar :: running"); //válido
10094 foo (["Phar", "running"); //válido
10095 foo ([new ReflectionClass ("stdClass"), "getName"]); //válido
10096 foo (function () {}); //válido
10097 foo ("no_such_function"); //callable esperado, string dada
10098 Os métodos não estáticos também podem ser passados como callables no formato
estático, resultando em um aviso e nível de reprovação
10099 Erro E_STRICT no PHP 7 e 5 respectivamente
10100 A visibilidade do método é levada em consideração Se o contexto do método com o
parâmetro selecionável não tiver acesso
10101 para o callable fornecido, terminará como se o método não existisse
10102 class Foo {
10103 função estática privada f () {
10104 eco "bom" PHP_EOL;
10105 }
10106 função estática pública r (chamavel $c) {
10107 $c ();
10108 }
10109 }
10110 função r (chamavel $c) {}
10111 Foo :: r (["Foo", "f"]);
10112 FF
10113 Notas PHP para Profissionais 250
10114 r (["Foo", "f"]);
10115 Saída:
10116 Erro fatal: TypeError não capturado: o argumento 1 passado para r () deve ser
chamado, array dado
10117 O suporte para tipos escalares de dicas de tipos foi adicionado no PHP 7 Isso
significa que ganhamos suporte a sugestões de tipos para
10118 booleanos, inteiros, floats e strings
10119 <?php
10120 função add (int $a, int $b) {
10121 devolve $a + $b;
10122 }
10123 var_dump (add (1, 2)); //Saídas "int (3)"
10124 Por padrão, o PHP tentará converter qualquer argumento fornecido para corresponder à
sua dica de tipo Alterando a chamada para adicionar (1.5, 2)
10125 dá exatamente a mesma saída, já que o float 1.5 foi convertido para int pelo PHP
10126 Para parar este comportamento, devese adicionar declare (strict_types = 1); para o
topo de todo arquivo fonte do PHP que o requer.
10127 <?php
10128 declarar (strict_types = 1);
10129 função add (int $a, int $b) {
10130 devolve $a + $b;
10131 }
10132 var_dump (add (1,5, 2));
10133 O script acima agora produz um erro fatal:
10134 Erro fatal: UnEught TypeError: O argumento 1 passado para add () deve ser do tipo
inteiro, float given
10135 Uma exceção: tipos especiais
10136 Algumas funções do PHP podem retornar um valor do tipo resource Como este não é um
tipo escalar, mas um tipo especial, não é
10137 possível digitar dicalo
10138 Por exemplo, curl_init () retornará um recurso, assim como fopen () Claro, esses
dois recursos não são
10139 compatíveis entre si Por causa disso, o PHP 7 sempre lançará o seguinte TypeError
quando digitar hinting
10140 Recurso explicitamente:
10141 TypeError: O argumento 1 passado para sample () deve ser uma instância de resource,
resource given
10142 Seção 45.3: Dicas de tipo anulável
10143 Parâmetros
10144 Sugestão de tipo anulável foi adicionada no PHP 7.1 usando o? operador antes da dica
de tipo.
10145 FF
10146 Notas PHP para Profissionais 251
10147 função f (? string $a) {}
10148 função g (string $a) {}
10149 f (nulo); //válido
10150 g (nulo); //TypeError: O argumento 1 passado para g () deve ser do tipo string, null
dado
10151 Antes do PHP 7.1, se um parâmetro tiver uma dica de tipo, ele deve declarar um valor
padrão nulo para aceitar valores nulos
10152 função f (string $a = null) {}
10153 função g (string $a) {}
10154 f (nulo); //válido
10155 g (nulo); //TypeError: O argumento 1 passado para g () deve ser do tipo string, null
dado
10156 Valores de retorno
10157 No PHP 7.0, as funções com um tipo de retorno não devem retornar null
10158 No PHP 7.1, as funções podem declarar uma dica de tipo de retorno anulável No
entanto, a função ainda deve retornar nulo, não anular
10159 (sem /instruções de retorno vazias)
10160 função f ():? string {
10161 return null;
10162 }
10163 função g ():? string {}
10164 função h ():? string {}
10165 f (); //ESTÁ BEM
10166 g (); //TypeError: valor de retorno de g () deve ser do tipo string ou null, nenhum
retornado
10167 h (); //TypeError: O valor de retorno de h () deve ser do tipo string ou null,
nenhum retornado
10168 Seção 45.4: Tipos de objetos genéricos insinuantes
10169 Como os objetos PHP não herdam de nenhuma classe base (incluindo stdClass), não há
suporte para o tipo insinuando um
10170 tipo de objeto genérico
10171 Por exemplo, o abaixo não funcionará
10172 <?php
10173 function doSomething (objeto $obj) {
10174 return $obj;
10175 }
10176 classe ClassOne {}
10177 classe ClassTwo {}
10178 $classOne = new ClassOne ();
10179 $classTwo = new ClassTwo ();
10180 doSomething ($classOne);
10181 doSomething ($classTwo);
10182 E vai lançar um erro fatal:
10183 Erro fatal: UnEught TypeError: O argumento 1 passado para doSomething () deve ser
uma instância de objeto,
10184 instância de OperationOne dada
10185 FF
10186 Notas PHP para Profissionais 252
10187 Uma solução para isso é declarar uma interface degenerada que não define métodos e
tem todos os seus objetos
10188 implementar essa interface
10189 <?php
10190 objeto de interface {}
10191 function doSomething (Objeto $obj) {
10192 return $obj;
10193 }
10194 classe ClassOne implementa o objeto {}
10195 classe ClassTwo implementa o objeto {}
10196 $classOne = new ClassOne ();
10197 $classTwo = new ClassTwo ();
10198 doSomething ($classOne);
10199 doSomething ($classTwo);
10200 Seção 45.5: Tipo Sugestões Sem Devolução (Anular)
10201 No PHP 7.1, o tipo de retorno void foi adicionado Enquanto o PHP não possui um valor
vazio, ele é geralmente entendido
10202 linguagens de programação que uma função que retorna nada está retornando vazia Isso
não deve ser confundido com
10203 retornando null, como null é um valor que pode ser retornado
10204 function lacks_return (): void {
10205 //válido
10206 }
10207 Observe que, se você declarar um retorno vazio, não poderá retornar nenhum valor ou
receberá um erro fatal:
10208 function should_return_nothing (): void {
10209 return null; //Erro fatal: uma função void não deve retornar um valor
10210 }
10211 No entanto, usar o retorno para sair da função é válido:
10212 function returns_nothing (): void {
10213 Retorna; //válido
10214 }
10215 FF
10216 Notas PHP para Profissionais 253
10217 Capítulo 46: Filtros e funções de filtro
10218 Detalhes do Parâmetro
10219 Valor variável para filtrar Observe que os valores escalares são convertidos em
string internamente antes de serem filtrados.
10220
10221 filtro
10222 O ID do filtro a ser aplicado A página de manual Tipos de filtros lista os filtros
disponíveis Se omitido,
10223 FILTER_DEFAULT será usado, o que equivale a FILTER_UNSAFE_RAW Isso resultará em
nenhuma filtragem
10224 ocorrendo por padrão
10225
10226 opções
10227 Matriz associativa de opções ou disjunção bit a bit de flags Se o filtro aceita
opções, os sinalizadores podem ser
10228 fornecido no campo "flags" do array Para o filtro "retorno de chamada", o tipo que
pode ser chamado deve ser passado O retorno de chamada
10229 deve aceitar um argumento, o valor a ser filtrado e retornar o valor após filtrálo
/sanitizálo
10230 Essa extensão filtra os dados validando ou sanitizandoos Isso é especialmente útil
quando a fonte de dados contém
10231 dados desconhecidos (ou estrangeiros), como entrada fornecida pelo usuário Por
exemplo, esses dados podem vir de um formulário HTML.
10232 Seção 46.1: Validando valores booleanos
10233 var_dump (filter_var (true, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
//verdade
10234 var_dump (filter_var (false, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
//false
10235 var_dump (filter_var (1, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //verdade
10236 var_dump (filter_var (0, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //false
10237 var_dump (filter_var ('1', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
//verdade
10238 var_dump (filter_var ('0', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //false
10239 var_dump (filter_var ('', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //false
10240 var_dump (filter_var ('', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //false
10241 var_dump (filter_var ('true', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
//verdade
10242 var_dump (filter_var ('false', FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE));
//false
10243 var_dump (filter_var ([], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //NULO
10244 var_dump (filter_var (null, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)); //false
10245 Seção 46.2: Validar um número é um flutuador
10246 Valida o valor como float e converte para float no sucesso
10247 var_dump (filter_var (1, FILTER_VALIDATE_FLOAT));
10248 var_dump (filter_var (1.0, FILTER_VALIDATE_FLOAT));
10249 var_dump (filter_var (1.0000, FILTER_VALIDATE_FLOAT));
10250 var_dump (filter_var (1.00001, FILTER_VALIDATE_FLOAT));
10251 var_dump (filter_var ('1', FILTER_VALIDATE_FLOAT));
10252 var_dump (filter_var ('1.0', FILTER_VALIDATE_FLOAT));
10253 var_dump (filter_var ('1,0000', FILTER_VALIDATE_FLOAT));
10254 var_dump (filter_var ('1.00001', FILTER_VALIDATE_FLOAT));
10255 var_dump (filter_var ('1.000', FILTER_VALIDATE_FLOAT));
10256 var_dump (filter_var ('1.000.0', FILTER_VALIDATE_FLOAT));
10257 var_dump (filter_var ('1,000.0000', FILTER_VALIDATE_FLOAT));
10258 var_dump (filter_var ('1.000.00001', FILTER_VALIDATE_FLOAT));
10259 var_dump (filter_var (1, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10260 var_dump (filter_var (1.0, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10261 var_dump (filter_var (1.0000, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10262 var_dump (filter_var (1.00001, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10263 var_dump (filter_var ('1', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10264 var_dump (filter_var ('1.0', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10265 var_dump (filter_var ('1,0000', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10266 var_dump (filter_var ('1.00001', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10267 FF
10268 Notas PHP para Profissionais 254
10269 var_dump (filter_var ('1.000', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10270 var_dump (filter_var ('1.000.0', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10271 var_dump (filter_var ('1,000.0000', FILTER_VALIDATE_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10272 var_dump (filter_var ('1.000.00001', FILTER_VALIDATE_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10273 Resultados
10274 flutuador (1)
10275 flutuador (1)
10276 flutuador (1)
10277 flutuar (1.00001)
10278 flutuador (1)
10279 flutuador (1)
10280 flutuador (1)
10281 flutuar (1.00001)
10282 bool (falso)
10283 bool (falso)
10284 bool (falso)
10285 bool (falso)
10286 flutuador (1)
10287 flutuador (1)
10288 flutuador (1)
10289 flutuar (1.00001)
10290 flutuador (1)
10291 flutuador (1)
10292 flutuador (1)
10293 flutuar (1.00001)
10294 flutuar (1000)
10295 flutuar (1000)
10296 flutuar (1000)
10297 flutuador (1000.00001)
10298 Seção 46.3: Validar um endereço MAC
10299 Valida um valor é um endereço MAC válido
10300 var_dump (filter_var ('FAF9DDB25E0D', FILTER_VALIDATE_MAC));
10301 var_dump (filter_var ('DCBB179ACE81', FILTER_VALIDATE_MAC));
10302 var_dump (filter_var ('96D59E6740AB ', FILTER_VALIDATE_MAC));
10303 var_dump (filter_var ('96D59E6740 ', FILTER_VALIDATE_MAC));
10304 var_dump (filter_var ('', FILTER_VALIDATE_MAC));
10305 Resultados:
10306 string (17) "FAF9DDB25E0D"
10307 corda (17) "DCBB179ACE81"
10308 string (17) "96D59E6740AB"
10309 bool (falso)
10310 bool (falso)
10311 Seção 46.4: Endereços de Email da Sanitze
10312 Remova todos os caracteres, exceto letras, dígitos e! # $% & '* + =? ^ _ `{|} ~ @ []
10313 var_dump (filter_var ('john@example.com', FILTER_SANITIZE_EMAIL));
10314 var_dump (filter_var ("! # $% & '* + =? ^ _` {|} ~ [] @ example.com ",
FILTER_SANITIZE_EMAIL));
10315 var_dump (filter_var ('john/@example.com ', FILTER_SANITIZE_EMAIL));
10316 FF
10317 Notas PHP para Profissionais 255
10318 var_dump (filter_var ('john \ @ example.com', FILTER_SANITIZE_EMAIL));
10319 var_dump (filter_var ('joh n@example.com', FILTER_SANITIZE_EMAIL));
10320 Resultados:
10321 string (16) "joao@example.com"
10322 string (33) "! # $% & '* + =? ^ _` {|} ~ [] @ example.com "
10323 string (16) "joao@example.com"
10324 string (16) "joao@example.com"
10325 string (16) "joao@example.com"
10326 Seção 46.5: Higienizar Inteiros
10327 Remova todos os caracteres, exceto os dígitos, sinal de mais e menos
10328 var_dump (filter_var (1, FILTER_SANITIZE_NUMBER_INT));
10329 var_dump (filter_var (1, FILTER_SANITIZE_NUMBER_INT));
10330 var_dump (filter_var (+1, FILTER_SANITIZE_NUMBER_INT));
10331 var_dump (filter_var (1,00, FILTER_SANITIZE_NUMBER_INT));
10332 var_dump (filter_var (+1.00, FILTER_SANITIZE_NUMBER_INT));
10333 var_dump (filter_var (1.00, FILTER_SANITIZE_NUMBER_INT));
10334 var_dump (filter_var ('1', FILTER_SANITIZE_NUMBER_INT));
10335 var_dump (filter_var (' 1', FILTER_SANITIZE_NUMBER_INT));
10336 var_dump (filter_var ('+ 1', FILTER_SANITIZE_NUMBER_INT));
10337 var_dump (filter_var ('1.00', FILTER_SANITIZE_NUMBER_INT));
10338 var_dump (filter_var ('+ 1,00', FILTER_SANITIZE_NUMBER_INT));
10339 var_dump (filter_var (' 1.00', FILTER_SANITIZE_NUMBER_INT));
10340 var_dump (filter_var ('1 unicorn', FILTER_SANITIZE_NUMBER_INT));
10341 var_dump (filter_var (' 1 unicorn', FILTER_SANITIZE_NUMBER_INT));
10342 var_dump (filter_var ('+ 1 unicórnio', FILTER_SANITIZE_NUMBER_INT));
10343 var_dump (filter_var ("! # $% & '* + =? ^ _` {|} ~ @ []
0123456789abcdefghijklmnopqrstuvwxyz ",
10344 FILTER_SANITIZE_NUMBER_INT));
10345 Resultados:
10346 string (1) "1"
10347 string (2) "1"
10348 string (1) "1"
10349 string (1) "1"
10350 string (1) "1"
10351 string (2) "1"
10352 string (1) "1"
10353 string (2) "1"
10354 string (2) "+1"
10355 string (3) "100"
10356 string (4) "+100"
10357 string (4) "100"
10358 string (1) "1"
10359 string (2) "1"
10360 string (2) "+1"
10361 string (12) "+ 0123456789"
10362 Seção 46.6: Sanitize URLs
10363 URLs Sanitze
10364 Remova todos os caracteres, exceto letras, dígitos e $_ +! * '(), {} | \ ^ ~ [] `<>
#%"; /?: @ & =
10365 FF
10366 Notas PHP para Profissionais 256
10367 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_SANITIZE_URL));
10368 var_dump (filter_var ("http: //www.example.com/path/to/dir/index.php? test = y! # $%
& '* + =? ^ _` {|} ~ []" ,
10369 FILTER_SANITIZE_URL));
10370 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=ab c')
10371 FILTER_SANITIZE_URL));
10372 Resultados:
10373 string (51) "http://www.example.com/path/to/dir/index.php?test=y"
10374 string (72) "http: //www.example.com/path/to/dir/index.php? test = y! # $% & '* +
=? ^ _` {|} ~ []"
10375 string (53) "http://www.example.com/path/to/dir/index.php?test=abc"
10376 Seção 46.7: Validar endereço de email
10377 Ao filtrar um endereço de email, filter_var () retornará os dados filtrados, nesse
caso, o endereço de email, ou falso se
10378 um endereço de email válido não pode ser encontrado:
10379 var_dump (filter_var ('john@example.com', FILTER_VALIDATE_EMAIL));
10380 var_dump (filter_var ('notValidEmail', FILTER_VALIDATE_EMAIL));
10381 Resultados:
10382 string (16) "joao@example.com"
10383 bool (falso)
10384 Esta função não valida caracteres não latinos O nome de domínio internacionalizado
pode ser validado em seus xn
10385 Formato
10386 Observe que você não pode saber se o endereço de email está correto antes de enviar
um email para ele Você pode querer fazer alguma
10387 verificações extras, como a verificação de um registro MX, mas isso não é necessário
Se você enviar um email de confirmação, não
10388 esqueça de remover contas não usadas após um curto período
10389 Seção 46.8: Validando um valor é um inteiro
10390 Ao filtrar um valor que deve ser um inteiro filter_var () retornará os dados
filtrados, neste caso o inteiro,
10391 ou false se o valor não for um inteiro Flutuadores não são inteiros:
10392 var_dump (filter_var ('10 ', FILTER_VALIDATE_INT));
10393 var_dump (filter_var ('a10', FILTER_VALIDATE_INT));
10394 var_dump (filter_var ('10a', FILTER_VALIDATE_INT));
10395 var_dump (filter_var ('', FILTER_VALIDATE_INT));
10396 var_dump (filter_var ('10 .00 ', FILTER_VALIDATE_INT));
10397 var_dump (filter_var ('10, 000 ', FILTER_VALIDATE_INT));
10398 var_dump (filter_var (' 5', FILTER_VALIDATE_INT));
10399 var_dump (filter_var ('+ 7', FILTER_VALIDATE_INT));
10400 Resultados:
10401 int (10)
10402 bool (falso)
10403 bool (falso)
10404 bool (falso)
10405 bool (falso)
10406 bool (falso)
10407 int (5)
10408 FF
10409 Notas PHP para Profissionais 257
10410 int (7)
10411 Se você está esperando apenas dígitos, você pode usar uma expressão regular:
10412 if (is_string ($_ GET ['entrada']) && preg_match ('# ^ [09] + $#', $_GET
['entrada']))
10413 //este é um inteiro de dígito (positivo)
10414 outro
10415 //entrada está incorreta
10416 Se você converter esse valor em um inteiro, não precisará fazer essa verificação e,
portanto, poderá usar filter_var
10417 Seção 46.9: Validando um Integer Falls em um intervalo
10418 Ao validar que um inteiro cai em um intervalo, a verificação inclui os limites
mínimo e máximo:
10419 $options = array (
10420 'opções' => array (
10421 'min_range' => 5,
10422 'max_range' => 10,
10423 )
10424 );
10425 var_dump (filter_var ('5', FILTER_VALIDATE_INT, $options));
10426 var_dump (filter_var ('10 ', FILTER_VALIDATE_INT, $options));
10427 var_dump (filter_var ('8', FILTER_VALIDATE_INT, $options));
10428 var_dump (filter_var ('4', FILTER_VALIDATE_INT, $options));
10429 var_dump (filter_var ('11 ', FILTER_VALIDATE_INT, $options));
10430 var_dump (filter_var (' 6', FILTER_VALIDATE_INT, $options));
10431 Resultados:
10432 int (5)
10433 int (10)
10434 int (8)
10435 bool (falso)
10436 bool (falso)
10437 bool (falso)
10438 Seção 46.10: validar uma URL
10439 Ao filtrar um URL, filter_var () retornará os dados filtrados, nesse caso, o URL, ou
false, se um URL válido não puder ser
10440 encontrado:
10441 URL: example.com
10442 var_dump (filter_var ('example.com', FILTER_VALIDATE_URL));
10443 var_dump (filter_var ('example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED));
10444 var_dump (filter_var ('example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_HOST_REQUIRED));
10445 var_dump (filter_var ('example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_PATH_REQUIRED));
10446 var_dump (filter_var ('example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_QUERY_REQUIRED));
10447 Resultados:
10448 bool (falso)
10449 bool (falso)
10450 bool (falso)
10451 bool (falso)
10452 bool (falso)
10453 FF
10454 Notas PHP para Profissionais 258
10455 URL: http://example.com
10456 var_dump (filter_var ('http://example.com', FILTER_VALIDATE_URL));
10457 var_dump (filter_var ('http://example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED));
10458 var_dump (filter_var ('http://example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_HOST_REQUIRED));
10459 var_dump (filter_var ('http://example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_PATH_REQUIRED));
10460 var_dump (filter_var ('http://example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_QUERY_REQUIRED));
10461 Resultados:
10462 string (18) "http://example.com"
10463 string (18) "http://example.com"
10464 string (18) "http://example.com"
10465 bool (falso)
10466 bool (falso)
10467 URL: http://www.example.com
10468 var_dump (filter_var ('http://www.example.com', FILTER_VALIDATE_URL));
10469 var_dump (filter_var ('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED));
10470 var_dump (filter_var ('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_HOST_REQUIRED));
10471 var_dump (filter_var ('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_PATH_REQUIRED));
10472 var_dump (filter_var ('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_QUERY_REQUIRED));
10473 Resultados:
10474 string (22) "http://www.example.com"
10475 string (22) "http://www.example.com"
10476 string (22) "http://www.example.com"
10477 bool (falso)
10478 bool (falso)
10479 URL: http://www.example.com/path/to/dir/
10480 var_dump (filter_var ('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL));
10481 var_dump (filter_var ('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
10482 FILTER_FLAG_SCHEME_REQUIRED));
10483 var_dump (filter_var ('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
10484 FILTER_FLAG_HOST_REQUIRED));
10485 var_dump (filter_var ('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
10486 FILTER_FLAG_PATH_REQUIRED));
10487 var_dump (filter_var ('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
10488 FILTER_FLAG_QUERY_REQUIRED));
10489 Resultados:
10490 string (35) "http://www.example.com/path/to/dir/"
10491 string (35) "http://www.example.com/path/to/dir/"
10492 string (35) "http://www.example.com/path/to/dir/"
10493 string (35) "http://www.example.com/path/to/dir/"
10494 bool (falso)
10495 URL: http://www.example.com/path/to/dir/index.php
10496 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php',
FILTER_VALIDATE_URL));
10497 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php',
FILTER_VALIDATE_URL,
10498 FILTER_FLAG_SCHEME_REQUIRED));
10499 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php',
FILTER_VALIDATE_URL,
10500 FF
10501 Notas PHP para Profissionais 259
10502 FILTER_FLAG_HOST_REQUIRED));
10503 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php',
FILTER_VALIDATE_URL,
10504 FILTER_FLAG_PATH_REQUIRED));
10505 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php',
FILTER_VALIDATE_URL,
10506 FILTER_FLAG_QUERY_REQUIRED));
10507 Resultados:
10508 string (44) "http://www.example.com/path/to/dir/index.php"
10509 string (44) "http://www.example.com/path/to/dir/index.php"
10510 string (44) "http://www.example.com/path/to/dir/index.php"
10511 string (44) "http://www.example.com/path/to/dir/index.php"
10512 bool (falso)
10513 URL: http://www.example.com/path/to/dir/index.php?test=y
10514 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL));
10515 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL,
10516 FILTER_FLAG_SCHEME_REQUIRED));
10517 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL,
10518 FILTER_FLAG_HOST_REQUIRED));
10519 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL,
10520 FILTER_FLAG_PATH_REQUIRED));
10521 var_dump (filter_var ('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL,
10522 FILTER_FLAG_QUERY_REQUIRED));
10523 Resultados:
10524 string (51) "http://www.example.com/path/to/dir/index.php?test=y"
10525 string (51) "http://www.example.com/path/to/dir/index.php?test=y"
10526 string (51) "http://www.example.com/path/to/dir/index.php?test=y"
10527 string (51) "http://www.example.com/path/to/dir/index.php?test=y"
10528 string (51) "http://www.example.com/path/to/dir/index.php?test=y"
10529 Aviso: Você deve verificar o protocolo para protegêlo contra um ataque XSS:
10530 var_dump (filter_var ('javascript: //comment% 0Aalert (1)', FILTER_VALIDATE_URL));
10531 //string (31) "javascript: //comentário% 0Aalert (1)"
10532 Seção 46.11: Higienizar Flutuantes
10533 Remova todos os caracteres, exceto dígitos, + e, opcionalmente, eE
10534 var_dump (filter_var (1, FILTER_SANITIZE_NUMBER_FLOAT));
10535 var_dump (filter_var (1.0, FILTER_SANITIZE_NUMBER_FLOAT));
10536 var_dump (filter_var (1.0000, FILTER_SANITIZE_NUMBER_FLOAT));
10537 var_dump (filter_var (1.00001, FILTER_SANITIZE_NUMBER_FLOAT));
10538 var_dump (filter_var ('1', FILTER_SANITIZE_NUMBER_FLOAT));
10539 var_dump (filter_var ('1.0', FILTER_SANITIZE_NUMBER_FLOAT));
10540 var_dump (filter_var ('1.0000', FILTER_SANITIZE_NUMBER_FLOAT));
10541 var_dump (filter_var ('1.00001', FILTER_SANITIZE_NUMBER_FLOAT));
10542 var_dump (filter_var ('1,000', FILTER_SANITIZE_NUMBER_FLOAT));
10543 var_dump (filter_var ('1.000.0', FILTER_SANITIZE_NUMBER_FLOAT));
10544 var_dump (filter_var ('1,000.0000', FILTER_SANITIZE_NUMBER_FLOAT));
10545 var_dump (filter_var ('1,000.00001', FILTER_SANITIZE_NUMBER_FLOAT));
10546 var_dump (filter_var ('1.8281e009', FILTER_SANITIZE_NUMBER_FLOAT));
10547 Resultados:
10548 FF
10549 Notas PHP para Profissionais 260
10550 string (1) "1"
10551 string (1) "1"
10552 string (1) "1"
10553 string (6) "100001"
10554 string (1) "1"
10555 string (2) "10"
10556 string (5) "10000"
10557 string (6) "100001"
10558 string (4) "1000"
10559 string (5) "10000"
10560 string (8) "10000000"
10561 string (9) "100000001"
10562 string (9) "18281009"
10563 Com a opção FILTER_FLAG_ALLOW_THOUSAND:
10564 var_dump (filter_var (1, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_THOUSAND));
10565 var_dump (filter_var (1.0, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10566 var_dump (filter_var (1.0000, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10567 var_dump (filter_var (1.00001, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10568 var_dump (filter_var ('1', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10569 var_dump (filter_var ('1.0', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10570 var_dump (filter_var ('1,0000', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10571 var_dump (filter_var ('1.00001', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10572 var_dump (filter_var ('1.000', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10573 var_dump (filter_var ('1.000.0', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10574 var_dump (filter_var ('1,000.0000', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10575 var_dump (filter_var ('1.000.00001', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10576 var_dump (filter_var ('1.8281e009', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_THOUSAND));
10577 Resultados:
10578 string (1) "1"
10579 string (1) "1"
10580 string (6) "100001"
10581 string (1) "1"
10582 string (2) "10"
10583 string (5) "10000"
10584 string (6) "100001"
10585 string (5) "1.000"
10586 string (6) "1,0000"
10587 string (9) "1,0000000"
10588 string (10) "1,00000001"
10589 string (9) "18281009"
10590 Com a opção FILTER_FLAG_ALLOW_SCIENTIFIC:
10591 var_dump (filter_var (1, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10592 var_dump (filter_var (1.0, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10593 var_dump (filter_var (1.0000, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10594 var_dump (filter_var (1.00001, FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10595 var_dump (filter_var ('1', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10596 var_dump (filter_var ('1.0', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10597 var_dump (filter_var ('1.0000', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10598 var_dump (filter_var ('1.00001', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10599 var_dump (filter_var ('1.000', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10600 var_dump (filter_var ('1.000.0', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10601 var_dump (filter_var ('1,000.0000', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10602 var_dump (filter_var ('1.000.00001', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10603 FF
10604 Notas PHP para Profissionais 261
10605 var_dump (filter_var ('1.8281e009', FILTER_SANITIZE_NUMBER_FLOAT,
FILTER_FLAG_ALLOW_SCIENTIFIC));
10606 Resultados:
10607 string (1) "1"
10608 string (1) "1"
10609 string (1) "1"
10610 string (6) "100001"
10611 string (1) "1"
10612 string (2) "10"
10613 string (5) "10000"
10614 string (6) "100001"
10615 string (4) "1000"
10616 string (5) "10000"
10617 string (8) "10000000"
10618 string (9) "100000001"
10619 string (10) "18281e009"
10620 Seção 46.12: Validar endereços IP
10621 Valida um valor é um endereço IP válido
10622 var_dump (filter_var ('185.158.24.24', FILTER_VALIDATE_IP));
10623 var_dump (filter_var ('2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001',
FILTER_VALIDATE_IP));
10624 var_dump (filter_var ('192.168.0.1', FILTER_VALIDATE_IP));
10625 var_dump (filter_var ('127.0.0.1', FILTER_VALIDATE_IP));
10626 Resultados:
10627 string (13) "185.158.24.24"
10628 string (39) "2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001"
10629 string (11) "192.168.0.1"
10630 string (9) "127.0.0.1"
10631 Valide um endereço IP IPv4 válido:
10632 var_dump (filter_var ('185.158.24.24', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
10633 var_dump (filter_var ('2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001',
FILTER_VALIDATE_IP,
10634 FILTER_FLAG_IPV4));
10635 var_dump (filter_var ('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
10636 var_dump (filter_var ('127.0.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
10637 Resultados:
10638 string (13) "185.158.24.24"
10639 bool (falso)
10640 string (11) "192.168.0.1"
10641 string (9) "127.0.0.1"
10642 Valide um endereço IP IPv6 válido:
10643 var_dump (filter_var ('185.158.24.24', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
10644 var_dump (filter_var ('2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001',
FILTER_VALIDATE_IP,
10645 FILTER_FLAG_IPV6));
10646 var_dump (filter_var ('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
10647 var_dump (filter_var ('127.0.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
10648 FF
10649 Notas PHP para Profissionais 262
10650 Resultados:
10651 bool (falso)
10652 string (39) "2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001"
10653 bool (falso)
10654 bool (falso)
10655 Validar um endereço IP não está em um intervalo privado:
10656 var_dump (filter_var ('185.158.24.24', FILTER_VALIDATE_IP,
FILTER_FLAG_NO_PRIV_RANGE));
10657 var_dump (filter_var ('2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001',
FILTER_VALIDATE_IP,
10658 FILTER_FLAG_NO_PRIV_RANGE));
10659 var_dump (filter_var ('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE));
10660 var_dump (filter_var ('127.0.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE));
10661 Resultados:
10662 string (13) "185.158.24.24"
10663 string (39) "2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001"
10664 bool (falso)
10665 string (9) "127.0.0.1"
10666 Validar um endereço IP não está em um intervalo reservado:
10667 var_dump (filter_var ('185.158.24.24', FILTER_VALIDATE_IP,
FILTER_FLAG_NO_RES_RANGE));
10668 var_dump (filter_var ('2001: 0db8: 0a0b: 12f0: 0000: 0000: 0000: 0001',
FILTER_VALIDATE_IP,
10669 FILTER_FLAG_NO_RES_RANGE));
10670 var_dump (filter_var ('192.168.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
10671 var_dump (filter_var ('127.0.0.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
10672 Resultados:
10673 string (13) "185.158.24.24"
10674 bool (falso)
10675 string (11) "192.168.0.1"
10676 bool (falso)
10677 Seção 46.13: limpeza de filtros
10678 podemos usar filtros para higienizar nossa variável de acordo com nossa necessidade
10679 Exemplo
10680 $string = "<p> Exemplo </p>";
10681 $newstring = filter_var ($string, FILTER_SANITIZE_STRING);
10682 var_dump ($newstring); //string (7) "Exemplo"
10683 acima irá remover as tags html da variável $string.
10684 FF
10685 Notas PHP para Profissionais 263
10686 Capítulo 47: Geradores
10687 Seção 47.1: A palavrachave de rendimento
10688 Uma declaração de rendimento é semelhante a uma declaração de retorno, exceto que,
em vez de parar a execução da função e
10689 retornando, o yield retorna um objeto Generator e pausa a execução da função do
gerador
10690 Aqui está um exemplo da função range, escrita como um gerador:
10691 função gen_one_to_three () {
10692 para ($i = 1; $i <= 3; $i ++) {
10693 //Observe que $i é preservado entre os rendimentos
10694 rende $i;
10695 }
10696 }
10697 Você pode ver que esta função retorna um objeto Generator inspecionando a saída de
var_dump:
10698 var_dump (gen_one_to_three ())
10699 # Saídas:
10700 Gerador de classe (0) {
10701 }
10702 Valores de rendimento
10703 O objeto Generator pode então ser iterado como uma matriz
10704 foreach (gen_one_to_three () como $value) {
10705 echo "$value \ n";
10706 }
10707 O exemplo acima irá gerar:
10708 123
10709 Produzindo Valores com Chaves
10710 Além de gerar valores, você também pode gerar pares chave /valor
10711 função gen_one_to_three () {
10712 $keys = ["primeiro", "segundo", "terceiro"];
10713 para ($i = 1; $i <= 3; $i ++) {
10714 //Observe que $i é preservado entre os rendimentos
10715 rendimento $keys [$i 1] => $i;
10716 }
10717 }
10718 foreach (gen_one_to_three () como $key => $value) {
10719 echo "$chave: $valor \ n";
10720 }
10721 O exemplo acima irá gerar:
10722 FF
10723 Notas PHP para Profissionais 264
10724 primeiro: 1
10725 segundo: 2
10726 terceiro: 3
10727 Seção 47.2: Lendo um arquivo grande com um gerador
10728 Um caso de uso comum para geradores é ler um arquivo do disco e iterar sobre seu
conteúdo Abaixo está uma aula que
10729 permite iterar em um arquivo CSV O uso de memória para este script é muito
previsível e não irá flutuar
10730 dependendo do tamanho do arquivo CSV
10731 <?php
10732 classe CsvReader
10733 {
10734 arquivo $protegido;
10735 função pública __construct ($filePath) {
10736 $this> file = fopen ($filePath, 'r');
10737 }
10738 linhas de função pública ()
10739 {
10740 while (! feof ($this> file)) {
10741 $row = fgetcsv ($this> arquivo, 4096);
10742 rendimento $linha;
10743 }
10744 Retorna;
10745 }
10746 }
10747 $csv = new CsvReader ('/caminho /para /enorme /csv /arquivo.csv');
10748 foreach ($csv> linhas () como $row) {
10749 //Faça algo com a linha CSV
10750 }
10751 Seção 47.3: Por que usar um gerador?
10752 Os geradores são úteis quando você precisa gerar uma coleção grande para depois
iterar Eles são mais simples
10753 alternativa à criação de uma classe que implemente um Iterator, que muitas vezes é
um exagero
10754 Por exemplo, considere a função abaixo
10755 função randomNumbers (int $length)
10756 {
10757 $array = [];
10758 para ($i = 0; $i <$length; $i ++) {
10759 $array [] = mt_rand (1, 10);
10760 }
10761 return $array;
10762 }
10763 Tudo isso faz uma função é uma matriz que é preenchida com números aleatórios Para
usálo, podemos fazer
10764 FF
10765 Notas PHP para Profissionais 265
10766 randomNumbers (10), que nos dará uma matriz de 10 números aleatórios E se quisermos
gerar um milhão
10767 Números aleatórios? randomNumbers (1000000) fará isso por nós, mas a um custo de
memória Um milhão de inteiros
10768 armazenado em uma matriz usa aproximadamente 33 megabytes de memória
10769 $startMemory = memory_get_usage ();
10770 $randomNumbers = randomNumbers (1000000);
10771 echo memory_get_usage () $startMemory, 'bytes';
10772 Isto é devido a todo o milhão de números aleatórios sendo gerados e retornados de
uma só vez, ao invés de um em um
10773 Tempo Os geradores são uma maneira fácil de resolver esse problema.
10774 Seção 47.4: Usando a função send () para passar valores para um
10775 gerador
10776 Os geradores são codificados rapidamente e, em muitos casos, uma alternativa
reduzida a implementações pesadas de iteradores Com o jejum
10777 implementação vem um pouco de falta de controle quando um gerador deve parar de
gerar ou se deve gerar
10778 algo mais No entanto, isso pode ser conseguido com o uso da função send (),
permitindo que o
10779 função para enviar parâmetros para o gerador após cada loop
10780 //Imaginando acessando uma grande quantidade de dados de um servidor, aqui está o
gerador para isso:
10781 function generateDataFromServerDemo ()
10782 {
10783 $indexCurrentRun = 0; //Neste exemplo no lugar de dados do servidor, eu apenas envio
feedback
10784 toda vez que um loop passava
10785 $timeout = false;
10786 while (! $timeout)
10787 {
10788 $timeout = yield $indexCurrentRun; //Os valores são passados para o chamador A
próxima vez que o
10789 gerador é chamado, ele vai começar nesta declaração Se send () for usado, $timeout
levará isso
10790 valor
10791 $indexCurrentRun ++;
10792 }
10793 yield 'X de bytes estão faltando </br> ';
10794 }
10795 //Comece a usar o gerador
10796 $generatorDataFromServer = generateDataFromServerDemo ();
10797 foreach ($generatorDataFromServer como $numberOfRuns)
10798 {
10799 if ($numberOfRuns <10)
10800 {
10801 echo $numberOfRuns "</br>";
10802 }
10803 outro
10804 {
10805 $generatorDataFromServer> send (true); //enviando dados para o gerador
10806 echo $generatorDataFromServer> current (); //acessando o elemento mais recente
(indicando quantas
10807 bytes ainda estão faltando
10808 }
10809 }
10810 Resultando nesta saída:
10811 FF
10812 Notas PHP para Profissionais 266
10813 FF
10814 Notas PHP para Profissionais 267
10815 Capítulo 48: UTF8
10816 Seção 48.1: Entrada
10817 Você deve verificar se todas as seqüências de caracteres recebidas são válidas em
UTF8 antes de tentar armazenálas ou usálas em qualquer lugar
10818 O mb_check_encoding () do PHP faz o truque, mas você tem que usálo consistentemente
Não há realmente nenhuma maneira de contornar
10819 isso, como clientes maliciosos podem enviar dados em qualquer codificação que eles
querem
10820 $string = $_REQUEST ['user_comment'];
10821 i f (! mb_check_encoding ($string, 'UTF8')) {
10822 //a string não é UTF8, portanto, recodifiquea
10823 $actualEncoding = mb_detect_encoding ($string);
10824 $string = mb_convert_encoding ($string, 'UTF8', $actualEncoding);
10825 }
10826 Se você estiver usando HTML5, poderá ignorar este último ponto Você deseja que todos
os dados enviados a você pelos navegadores sejam
10827 em UTF8 A única maneira confiável de fazer isso é adicionar o atributo acceptcharset
a todas as tags <form>, como
10828 assim:
10829 <formulário action = "somepage.php" acceptcharset = "UTF8">
10830 Seção 48.2: Saída
10831 Se o seu aplicativo transmitir texto para outros sistemas, eles também precisarão
ser informados do caractere
10832 codificação No PHP, você pode usar a opção default_charset no php.ini, ou
manualmente emitir o ContentType
10833 Cabeçalho MIME você mesmo Esse é o método preferido ao segmentar navegadores modernos.
10834 header ('Tipo de Conteúdo: text /html; charset = utf8');
10835 Se você não conseguir definir os cabeçalhos de resposta, também poderá definir a
codificação em um documento HTML com
10836 Metadados HTML
10837 HTML5
10838 <meta charset = "utf8">
10839 Versões mais antigas do HTML
10840 <meta httpequiv = "Tipo de conteúdo" content = "text /html; charset = utf8" />
10841 Seção 48.3: Armazenamento e Acesso de Dados
10842 Este tópico fala especificamente sobre UTF8 e considerações para usálo com um banco
de dados Se você quiser mais
10843 informações sobre o uso de bancos de dados no PHP e, em seguida, confira este tópico
10844 Armazenando dados em um banco de dados MySQL:
10845 Especifique o conjunto de caracteres utf8mb4 em todas as tabelas e colunas de texto
em seu banco de dados Isso faz com que o MySQL
10846 armazene fisicamente e recupere valores codificados nativamente em UTF8.
10847 FF
10848 Notas PHP para Profissionais 268
10849 O MySQL implicitamente usará a codificação utf8mb4 se um agrupamento utf8mb4_ * for
especificado (sem qualquer
10850 conjunto de caracteres)
10851 Versões mais antigas do MySQL (<5.5.3) não suportam utf8mb4, então você será forçado
a usar o utf8, que somente
10852 suporta um subconjunto de caracteres Unicode
10853 Acessando dados em um banco de dados MySQL:
10854 No código do seu aplicativo (por exemplo, PHP), em qualquer método de acesso ao
banco de dados que você usa, você precisará definir a conexão
10855 charset para utf8mb4 Desta forma, o MySQL não faz nenhuma conversão de seu UTF8
nativo quando entrega dados para seu
10856 aplicação e viceversa
10857 Alguns drivers fornecem seu próprio mecanismo para configurar o conjunto de
caracteres de conexão, ambos atualizados
10858 seu próprio estado interno e informa ao MySQL a codificação a ser usada na conexão
Este é geralmente o
10859 abordagem preferida
10860 Por exemplo (A mesma consideração em relação ao utf8mb4 /utf8 se aplica como acima):
10861 Se você está usando a camada de abstração PDO com PHP = 5.3.6, você pode especificar
charset no DSN:
10862 $handle = new PDO ('mysql: charset = utf8mb4');
10863 Se você estiver usando o mysqli, você pode chamar set_charset ():
10864 $conn = mysqli_connect ('localhost', 'meu_usuário', 'minha_password', 'meu_db');
10865 $conn> set_charset ('utf8mb4'); //estilo orientado a objetos
10866 mysqli_set_charset ($conn, 'utf8mb4'); //estilo processual
10867 Se você está preso com o mysql simples, mas por acaso estiver executando o PHP =
5.2.3, você pode chamar mysql_set_charset
10868 $conn = mysql_connect ('localhost', 'meu_usuário', 'minha_password');
10869 $conn> set_charset ('utf8mb4'); //estilo orientado a objetos
10870 mysql_set_charset ($conn, 'utf8mb4'); //estilo processual
10871 Se o driver de banco de dados não fornecer seu próprio mecanismo para definir o
conjunto de caracteres de conexão,
10872 você pode ter que emitir uma consulta para informar ao MySQL como seu aplicativo
espera dados na conexão
10873 ser codificado: SET NAMES 'utf8mb4'.
10874 FF
10875 Notas PHP para Profissionais 269
10876 Capítulo 49: Suporte a Unicode em PHP
10877 Seção 49.1: Convertendo caracteres Unicode em “\ uxxxx”
10878 formato usando PHP
10879 Você pode usar o seguinte código para voltar e avançar
10880 if (! function_exists ('codepoint_encode')) {
10881 função codepoint_encode ($str) {
10882 return substr (json_encode ($str), 1, 1);
10883 }
10884 }
10885 if (! function_exists ('codepoint_decode')) {
10886 função codepoint_decode ($str) {
10887 return json_decode (sprintf ('"% s"', $str));
10888 }
10889 }
10890 Como usar:
10891 echo "\\ nUse codificação /decodificação JSON \\ n";
10892 var_dump (codepoint_encode (".."));
10893 var_dump (codepoint_decode ('\\ u6211 \\ u597d'));
10894 Saída:
10895 Use codificação /decodificação JSON
10896 string (12) "\\ u6211 \\ u597d"
10897 string (6) ".."
10898 Seção 49.2: Convertendo caracteres Unicode em seus valores numéricos
10899 valor e /ou entidades HTML usando PHP
10900 Você pode usar o seguinte código para voltar e avançar
10901 if (! function_exists ('mb_internal_encoding')) {
10902 função mb_internal_encoding ($encoding = NULL) {
10903 return ($from_encoding === NULL)? iconv_get_encoding (): iconv_set_encoding
($codificação);
10904 }
10905 }
10906 if (! function_exists ('mb_convert_encoding')) {
10907 função mb_convert_encoding ($str, $to_encoding, $from_encoding = NULL) {
10908 return iconv (($from_encoding === NULL)? mb_internal_encoding (): $from_encoding,
10909 $to_encoding, $str);
10910 }
10911 }
10912 if (! function_exists ('mb_chr')) {
10913 função mb_chr ($ord, $encoding = 'UTF8') {
10914 if ($codificação === 'UCS4BE') {
10915 pacote de retorno ("N", $ord);
10916 } outro {
10917 return mb_convert_encoding (mb_chr ($ord, 'UCS4BE'), $codificação, 'UCS4BE');
10918 }
10919 }
10920 }
10921 FF
10922 Notas PHP para Profissionais 270
10923 if (! function_exists ('mb_ord')) {
10924 função mb_ord ($char, $encoding = 'UTF8') {
10925 if ($codificação === 'UCS4BE') {
10926 list (, $ord) = (strlen ($char) === 4)? @unpack ('N', $char): @unpack ('n', $char);
10927 devolve $ord;
10928 } outro {
10929 return mb_ord (mb_convert_encoding ($char, 'UCS4BE', $codificação), 'UCS4BE');
10930 }
10931 }
10932 }
10933 if (! function_exists ('mb_htmlentities')) {
10934 função mb_htmlentities ($string, $hex = true, $codificação = 'UTF8') {
10935 return preg_replace_callback ('/[\ x {80} \ x {10FFFF}] /u', uso da função ($match)
($hex) {
10936 return sprintf ($hex? '& # x% X;': '& #% d;', mb_ord ($correspondência [0]));
10937 }, $string);
10938 }
10939 }
10940 if (! function_exists ('mb_html_entity_decode')) {
10941 função mb_html_entity_decode ($string, $flags = null, $codificação = 'UTF8') {
10942 return html_entity_decode ($string, ($flags === NULL)? ENT_COMPAT | ENT_HTML401:
$flags,
10943 $codificação);
10944 }
10945 }
10946 Como usar :
10947 echo "Obter string do valor numérico do DEC \ n";
10948 var_dump (mb_chr (50319, 'UCS4BE'));
10949 var_dump (mb_chr (271));
10950 echo "\ nReceba string a partir do valor HEX numérico \ n";
10951 var_dump (mb_chr (0xC48F, 'UCS4BE'));
10952 var_dump (mb_chr (0x010F));
10953 echo "\ nObtenha valor numérico de caractere como string DEC \ n";
10954 var_dump (mb_ord ('d', 'UCS4BE'));
10955 var_dump (mb_ord ('d'));
10956 echo "\ nObter valor numérico de caractere como string HEX \ n";
10957 var_dump (dechex (mb_ord ('d', 'UCS4BE')));
10958 var_dump (dechex (mb_ord ('d')));
10959 echo "\ nCodifique /decodifique para entidades HTML baseadas em DEC \ n";
10960 var_dump (mb_htmlentities ('tch', falso));
10961 var_dump (mb_html_entity_decode ('tch & # 252; & # 223;'));
10962 echo "\ nCodifique /decodifique para entidades HTML baseadas em HEX \ n";
10963 var_dump (mb_htmlentities ('tch '));
10964 var_dump (mb_html_entity_decode ('tch & # xFC; & # xDF;'));
10965 Saída:
10966 Obter string do valor numérico do DEC
10967 string (4) "d"
10968 string (2) "d"
10969 Obter string do valor numérico HEX
10970 string (4) "d"
10971 string (2) "d"
10972 FF
10973 Notas PHP para Profissionais 271
10974 Obter valor numérico de caractere como DEC int
10975 int (50319)
10976 int (271)
10977 Obter valor numérico de caractere como string HEX
10978 string (4) "c48f"
10979 string (3) "10f"
10980 Codificar /decodificar para entidades HTML baseadas em DEC
10981 string (15) "tch & # 252; & # 223;"
10982 string (7) "tch"
10983 Codificar /decodificar para entidades HTML baseadas em HEX
10984 string (15) "tch & # xFC; & # xDF;"
10985 string (7) "tch"
10986 Seção 49.3: Extensão internacional para suporte a Unicode
10987 As funções de string nativas são mapeadas para funções de byte único, elas não
funcionam bem com Unicode As extensões
10988 O iconv e o mbstring oferecem algum suporte ao Unicode, enquanto o Intlextention
oferece suporte total Intl é um invólucro para
10989 a biblioteca de ICU padrão de facto, consulte http://site.icuproject.org para obter
informações detalhadas que não estão disponíveis em
10990 http://php.net/manual/en/book.intl.php Se você não pode instalar a extensão, dê uma
olhada em uma alternativa
10991 implementação do Intl a partir do framework Symfony
10992 A UTI oferece uma internacionalização completa, da qual o Unicode é apenas uma parte
menor Você pode fazer transcodificação facilmente:
10993 \ UConverter :: transcode ($sString, 'UTF8', 'UTF8'); //tira bytes inválidos contra
ataques
10994 Mas, não desista iconv apenas ainda, considere:
10995 \ iconv ('UTF8', 'ASCII //TRANSLIT', "Cli ‫ כ‬nt"); //output: "Client"
10996 FF
10997 Notas PHP para Profissionais 272
10998 Capítulo 50: URLs
10999 Seção 50.1: analisando uma URL
11000 Para separar um URL em seus componentes individuais, use parse_url ():
11001 $url = 'http://www.example.com/page?foo=1&bar=baz#anchor';
11002 $parts = parse_url ($url);
11003 Depois de executar o acima, o conteúdo de $partes seria:
11004 Matriz
11005 (
11006 [esquema] => http
11007 [host] => www.example.com
11008 [caminho] => /page
11009 [consulta] => foo = 1 & bar = baz
11010 [fragmento] => âncora
11011 )
11012 Você também pode retornar seletivamente apenas um componente da URL Para retornar
apenas a querystring:
11013 $url = 'http://www.example.com/page?foo=1&bar=baz#anchor';
11014 $queryString = parse_url ($url, PHP_URL_QUERY);
11015 Qualquer uma das seguintes constantes são aceitas: PHP_URL_SCHEME, PHP_URL_HOST,
PHP_URL_PORT, PHP_URL_USER,
11016 PHP_URL_PASS, PHP_URL_PATH, PHP_URL_QUERY e PHP_URL_FRAGMENT
11017 Para analisar mais uma cadeia de consulta em pares de valores de chave, use
parse_str ():
11018 $params = [];
11019 parse_str ($queryString, $params);
11020 Após a execução do acima, o array $params seria preenchido com o seguinte:
11021 Matriz
11022 (
11023 [foo] => 1
11024 [bar] => baz
11025 )
11026 Seção 50.2: criar uma string de consulta codificada por URL de um
11027 matriz
11028 O http_build_query () criará uma string de consulta a partir de uma matriz ou objeto
Essas cadeias podem ser anexadas a um URL
11029 para criar uma solicitação GET ou usada em uma solicitação POST com, por exemplo,
cURL
11030 $parameters = array (
11031 'parameter1' => 'foo',
11032 'parameter2' => 'bar',
11033 );
11034 $queryString = http_build_query ($parameters);
11035 $queryString terá o seguinte valor:
11036 FF
11037 Notas PHP para Profissionais 273
11038 parâmetro1 = foo & parâmetro2 = bar
11039 http_build_query () também funcionará com matrizes multidimensionais:
11040 $parameters = array (
11041 "parameter3" => array (
11042 "sub1" => "foo",
11043 "sub2" => "bar",
11044 )
11045 "parameter4" => "baz",
11046 );
11047 $queryString = http_build_query ($parameters);
11048 $queryString terá este valor:
11049 parâmetro3% 5Bsub1% 5D = foo e parâmetro3% 5Bsub2% 5D = bar & parâmetro4 = baz
11050 que é a versão codificada por URL do
11051 parâmetro3 [sub1] = foo e parâmetro3 [sub2] = bar e parâmetro4 = baz
11052 Seção 50.3: redirecionando para outro URL
11053 Você pode usar a função header () para instruir o navegador a redirecionar para um
URL diferente:
11054 $url = 'https://example.org/foo/bar';
11055 if (! headers_sent ()) {//verificar cabeçalhos você não pode enviar cabeçalhos se
eles já tiverem enviado
11056 cabeçalho ('Localização:' $url);
11057 Saída; //protege do código que está sendo executado após a solicitação de
redirecionamento
11058 } outro {
11059 throw new Exception ('Não é possível redirecionar, cabeçalhos já enviados');
11060 }
11061 Você também pode redirecionar para uma URL relativa (isso não faz parte da
especificação HTTP oficial, mas funciona em todos
11062 navegadores):
11063 $url = 'foo /bar';
11064 if (! headers_sent ()) {
11065 cabeçalho ('Localização:' $url);
11066 Saída;
11067 } outro {
11068 throw new Exception ('Não é possível redirecionar, cabeçalhos já enviados');
11069 }
11070 Se os cabeçalhos foram enviados, você pode, alternativamente, enviar uma tag HTML de
atualização meta
11071 AVISO: A tag de atualização de meta depende de o HTML ser processado corretamente
pelo cliente e alguns não farão isso
11072 Em geral, só funciona em navegadores da web Além disso, considere que se os
cabeçalhos foram enviados, você pode ter um bug e
11073 isso deve acionar uma exceção
11074 Você também pode imprimir um link para os usuários clicarem, para clientes que
ignoram a tag de atualização meta:
11075 $url = 'https://example.org/foo/bar';
11076 if (! headers_sent ()) {
11077 cabeçalho ('Localização:' $url);
11078 } outro {
11079 FF
11080 Notas PHP para Profissionais 274
11081 $saveUrl = htmlspecialchars ($url); //protege do navegador que vê o URL como HTML
11082 //diz ao navegador para redirecionar a página para $saveUrl após 0 segundos
11083 print '<meta httpequiv = "atualizar" content = "0; url =' $saveUrl '"';
11084 //mostra o link para o usuário
11085 print '<p> Por favor, continue para <a href="' $saveUrl.'">' $saveUrl '</a> </p>';
11086 }
11087 Saída;
11088 FF
11089 Notas PHP para Profissionais 275
11090 Capítulo 51: Como dividir um URL
11091 Como você codifica o PHP, você provavelmente se colocará em uma posição em que você
precisa dividir um URL em vários
11092 peças Há obviamente mais de uma maneira de fazer isso dependendo de suas
necessidades Este artigo explicará aqueles
11093 maneiras para você, assim você pode encontrar o que funciona melhor para você
11094 Seção 51.1: Usando parse_url ()
11095 parse_url (): Esta função analisa um URL e retorna um array associativo contendo
qualquer um dos vários
11096 componentes da URL que estão presentes
11097 $url = parse_url ('http://example.com/project/controller/action/param1/param2');
11098 Matriz
11099 (
11100 [esquema] => http
11101 [host] => example.com
11102 [caminho] => /project /controller /action /param1 /param2
11103 )
11104 Se você precisar do caminho separado, você pode usar explodir
11105 $url = parse_url ('http://example.com/project/controller/action/param1/param2');
11106 $url ['sections'] = explode ('/', $url ['caminho']);
11107 Matriz
11108 (
11109 [esquema] => http
11110 [host] => example.com
11111 [caminho] => /project /controller /action /param1 /param2
11112 [seções] => Matriz
11113 (
11114 [0] =>
11115 [1] => projeto
11116 [2] => controlador
11117 [3] => ação
11118 [4] => param1
11119 [5] => param2
11120 )
11121 )
11122 Se você precisar da última parte da seção, você pode usar end () assim:
11123 $last = end ($url ['seções']);
11124 Se o URL contiver GET vars, você poderá recuperálos também
11125 $url = parse_url ('http://example.com?var1=value1&var2=value2');
11126 Matriz
11127 (
11128 [esquema] => http
11129 [host] => example.com
11130 [query] => var1 = valor1 e var2 = valor2
11131 FF
11132 Notas PHP para Profissionais 276
11133 )
11134 Se você deseja dividir a query vars, você pode usar parse_str () assim:
11135 $url = parse_url ('http://example.com?var1=value1&var2=value2');
11136 parse_str ($url ['query'], $partes);
11137 Matriz
11138 (
11139 [var1] => valor1
11140 [var2] => valor2
11141 )
11142 Seção 51.2: Usando o explode ()
11143 explode (): Retorna uma matriz de strings, cada uma das quais é uma substring da
string formada dividindoa
11144 limites formados pelo delimitador de cadeia
11145 Esta função é bastante direta
11146 $url = "http://example.com/project/controller/action/param1/param2";
11147 $parts = explode ('/', $url);
11148 Matriz
11149 (
11150 [0] => http:
11151 [1] =>
11152 [2] => example.com
11153 [3] => projeto
11154 [4] => controlador
11155 [5] => ação
11156 [6] => param1
11157 [7] => param2
11158 )
11159 Você pode recuperar a última parte do URL fazendo isso:
11160 $last = end ($partes);
11161 //Output: param2
11162 Você também pode navegar dentro da matriz usando sizeof () em combinação com um
operador de matemática como este:
11163 echo $parts [sizeof ($partes) 2];
11164 //Output: param1
11165 Seção 51.3: Usando basename ()
11166 basename (): Dada uma string contendo o caminho para um arquivo ou diretório, esta
função retornará o trailing
11167 componente de nome
11168 Esta função irá retornar apenas a última parte de um URL
11169 $url = "http://example.com/project/controller/action/param1/param2";
11170 FF
11171 Notas PHP para Profissionais 277
11172 $parts = basename ($url);
11173 //Output: param2
11174 Se o seu URL tem mais coisas para ele e o que você precisa é o nome do diretório que
contém o arquivo, você pode usálo com dirname ()
11175 como isso:
11176 $url = "http://example.com/project/controller/action/param1/param2/index.php";
11177 $parts = basename (dirname ($url));
11178 //Output: param2
11179 FF
11180 Notas PHP para Profissionais 278
11181 Capítulo 52: Serialização de Objetos
11182 Seção 52.1: Serialize /Unserialize
11183 serialize () retorna uma string contendo uma representação de fluxo de bytes de
qualquer valor que possa ser armazenado em PHP
11184 unserialize () pode usar essa string para recriar os valores das variáveis originais
11185 Para serializar um objeto
11186 serializar (objeto $);
11187 Para desserializar um objeto
11188 unserialize (objeto $)
11189 Exemplo
11190 $array = array ();
11191 $array ["a"] = "Foo";
11192 $array ["b"] = "Barra";
11193 $array ["c"] = "Baz";
11194 $array ["d"] = "Wom";
11195 $serializedArray = serialize ($array);
11196 echo $serializedArray; //saída:
11197 a: 4: {s: 1: "a"; s: 3: "Foo"; s: 1: "b"; s: 3: "Bar"; s: 1: "c"; s: 3: " Baz "; s:
1:" d "; s: 3:" Wom ";}
11198 Seção 52.2: A interface serializável
11199 Introdução
11200 As classes que implementam essa interface não suportam mais __sleep () e __wakeup ()
O método serializar
11201 é chamado sempre que uma instância precisa ser serializada Isso não invoca
__destruct () ou tem qualquer
11202 outro efeito colateral, a menos que seja programado dentro do método Quando os dados
não são serializados, a classe é
11203 conhecido e o método unserialize apropriado () é chamado como um construtor em vez
de chamar
11204 __construir() Se você precisar executar o construtor padrão, poderá fazêlo no método.
11205 Uso básico
11206 classe obj implementa Serializable {
11207 dados $privados;
11208 função pública __construct () {
11209 $this> data = "Meus dados privados";
11210 }
11211 public function serialize () {
11212 return serialize ($this> dados);
11213 }
11214 função pública unserialize ($data) {
11215 $this> data = unserialize ($data);
11216 }
11217 função pública getData () {
11218 retornar $this> data;
11219 }
11220 }
11221 FF
11222 Notas PHP para Profissionais 279
11223 $obj = new obj;
11224 $ser = serialize ($obj);
11225 var_dump ($ser); //Saída: string (38) "C: 3:" obj ": 23: {s: 15:" Meus dados
privados ";}"
11226 $newobj = unserialize ($ser);
11227 var_dump ($newobj> getData ()); //Output: string (15) "Meus dados privados"
11228 FF
11229 Notas PHP para Profissionais 280
11230 Capítulo 53: Serialização
11231 Detalhes do Parâmetro
11232 valor
11233 O valor a ser serializado serialize () manipula todos os tipos, exceto o tipo de
recurso Você também pode
11234 Matrizes serialize () que contêm referências para si próprio Referências circulares
dentro da matriz /objeto que você é
11235 serialização também será armazenado Qualquer outra referência será perdida Ao
serializar objetos, o PHP
11236 tente chamar a função de membro __sleep () antes da serialização Isso é para
permitir que o objeto faça
11237 limpeza de última hora, etc antes de ser serializado Da mesma forma, quando o objeto
é restaurado usando
11238 unserialize () a função de membro __wakeup () é chamada Os membros privados do
objeto têm o nome da classe
11239 prefixado ao nome do membro; membros protegidos têm um '*' prefixado ao nome do
membro.
11240 Esses valores prédefinidos têm bytes nulos em ambos os lados
11241 Seção 53.1: Serialização de tipos diferentes
11242 Gera uma representação armazenável de um valor
11243 Isso é útil para armazenar ou passar valores do PHP sem perder seu tipo e estrutura
11244 Para tornar a string serializada em um valor PHP novamente, use unserialize ()
11245 Serializando uma string
11246 $string = "Olá mundo";
11247 echo serialize ($string);
11248 //Output:
11249 //s: 11: "Olá mundo";
11250 Serializando um duplo
11251 $double = 1,5;
11252 serialização de eco ($double);
11253 //Output:
11254 //d: 1,5;
11255 Serializando um flutuador
11256 Float get serializado como duplas
11257 Serializando um inteiro
11258 $inteiro = 65;
11259 echo serialize ($integer);
11260 //Output:
11261 //i: 65;
11262 Serializando um booleano
11263 $boolean = true;
11264 echo serialize ($booleano);
11265 //Output:
11266 //b: 1;
11267 $boolean = false;
11268 echo serialize ($booleano);
11269 //Output:
11270 //b: 0;
11271 Serializando null
11272 FF
11273 Notas PHP para Profissionais 281
11274 $null = null;
11275 serialização de eco ($null);
11276 //Output:
11277 //N;
11278 Serializando uma matriz
11279 $array = array (
11280 25,
11281 'Corda',
11282 'Array' => ['Multi Dimension', 'Array'],
11283 'boolean' => true,
11284 'Objeto' => $obj, //$obj acima do Exemplo
11285 nulo,
11286 3,445
11287 );
11288 //Isso causará erro fatal
11289 //$array ['function'] = function () {retorno "função"; };
11290 echo serialize ($array);
11291 //Output:
11292 //a: 7: {i: 0; i: 25; i: 1; s: 6: "String"; s: 5: "Array"; a: 2: {i: 0; s: 15:
"Multi Dimensão "; i: 1; s: 5:" Matriz ";} s: 7:" booleano "; b: 1; s: 6:" Objeto ";
O: 3:" abc ": 1: {s: 1 : "i"; i: 1;} i: 2; N; i: 3; d: 3,44 49999999999998;}
11293 Serializando um objeto
11294 Você também pode serializar objetos
11295 Ao serializar objetos, o PHP tentará chamar a função de membro __sleep () antes da
serialização Isso é para
11296 permitir que o objeto faça qualquer limpeza de último minuto, etc antes de ser
serializado Da mesma forma, quando o objeto é restaurado
11297 usando unserialize () a função de membro __wakeup () é chamada
11298 class abc {
11299 var $i = 1;
11300 função foo () {
11301 retornar 'olá mundo';
11302 }
11303 }
11304 $object = new abc ();
11305 echo serialize (objeto $);
11306 //Output:
11307 //O: 3: "abc": 1: {s: 1: "i"; i: 1;}
11308 Observe que os Closures não podem ser serializados:
11309 $function = function () {echo 'Olá mundo!'; };
11310 $function (); //imprime "olá!"
11311 $serializedResult = serialize ($função); //Erro fatal: exceção não capturada
'Exception' com
11312 mensagem 'Serialização de' Encerramento 'não é permitida'
11313 Seção 53.2: Problemas de segurança com unserialize
11314 Usar a função de desserialização para desserializar dados da entrada do usuário pode
ser perigoso.
11315 FF
11316 Notas PHP para Profissionais 282
11317 Um aviso do php.net
11318 Aviso Não passe a entrada do usuário não confiável para unserialize () A falta de
serialização pode resultar em código sendo
11319 carregado e executado devido a instanciação de objetos e autoloading, e um usuário
malintencionado pode ser capaz de
11320 explorar isso Use um formato padrão de intercâmbio de dados seguro, como JSON (via
json_decode () e
11321 json_encode ()) se você precisar passar dados serializados para o usuário
11322 Possíveis ataques
11323 Injeção de Objeto PHP
11324 Injeção de Objeto PHP
11325 O PHP Object Injection é uma vulnerabilidade em nível de aplicativo que pode
permitir que um invasor execute diferentes tipos de
11326 ataques maliciosos, como Injeção de Código, Injeção de SQL, Traversal de Caminho e
Negação de Serviço de Aplicativo, dependendo
11327 no contexto A vulnerabilidade ocorre quando a entrada fornecida pelo usuário não é
adequadamente higienizada antes de ser passada para
11328 a função PHP unserialize () Como o PHP permite a serialização de objetos, os
invasores poderiam passar strings serializadas adhoc para
11329 uma chamada unserialize () vulnerável, resultando em uma injeção arbitrária de
objetos PHP no escopo do aplicativo
11330 Para explorar com sucesso uma vulnerabilidade de injeção de objetos PHP, duas
condições devem ser atendidas:
11331 O aplicativo deve ter uma classe que implemente um método mágico do PHP (como
__wakeup ou __destruct)
11332 que pode ser usado para realizar ataques malintencionados ou para iniciar uma
"cadeia POP"
11333 Todas as classes usadas durante o ataque devem ser declaradas quando o vulnerável
unserialize () está sendo
11334 chamado, caso contrário, o carregamento automático do objeto deve ser suportado para
essas classes
11335 Exemplo 1 Ataque de Traversal de Caminho
11336 O exemplo abaixo mostra uma classe PHP com um método __destruct explorável:
11337 classe Example1
11338 {
11339 public $cache_file;
11340 function __construct ()
11341 {
11342 //algum código PHP .
11343 }
11344 função __destruct ()
11345 {
11346 $file = "/var /www /cache /tmp /{$este> cache_file}";
11347 if (file_exists ($file)) @unlink ($arquivo);
11348 }
11349 }
11350 //algum código PHP .
11351 $user_data = unserialize ($_ GET ['dados']);
11352 //algum código PHP .
11353 Neste exemplo, um invasor pode excluir um arquivo arbitrário por meio de um ataque
Path Traversal, por exemplo, solicitando
11354 o seguinte URL:
11355 FF
11356 Notas PHP para Profissionais 283
11357 http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../inde
x.php ";}
11358 Exemplo 2 ataque de injeção de código
11359 O exemplo abaixo mostra uma classe PHP com um método __wakeup explorável:
11360 classe Example2
11361 {
11362 $gancho privado;
11363 function __construct ()
11364 {
11365 //algum código PHP .
11366 }
11367 função __wakeup ()
11368 {
11369 if (isset ($this> hook)) eval ($this> gancho);
11370 }
11371 }
11372 //algum código PHP .
11373 $user_data = unserialize ($_ COOKIE ['dados']);
11374 //algum código PHP .
11375 Neste exemplo, um invasor pode executar um ataque de injeção de código enviando uma
solicitação HTTP como esta:
11376 GET /vuln.php HTTP /1.0
11377 Anfitrião: testsite.com
11378 Biscoito:
11379 dados = O% 3A8% 3A% 22Exemplo2% 22% 3A1% 3A% 7Bs% 3A14% 3A% 22% 00Exemplo2% 00hook%
22% 3Bs% 3A10% 3A% 22phpinfo% 28% 29%
11380 3B% 22% 3B% 7D
11381 Conexão: fechar
11382 Onde o parâmetro de cookie "data" foi gerado pelo seguinte script:
11383 classe Example2
11384 {
11385 private $hook = "phpinfo ();";
11386 }
11387 print urlencode (serialize (new Example2));
11388 FF
11389 Notas PHP para Profissionais 284
11390 Capítulo 54: Encerramento
11391 Seção 54.1: Uso básico de um fechamento
11392 Um encerramento é o equivalente em PHP de uma função anônima, por exemplo uma função
que não tem nome Mesmo que isso seja
11393 tecnicamente não está correto, o comportamento de um fechamento permanece igual ao
de uma função, com alguns recursos extras
11394 Um encerramento não é senão um objeto da classe Closure que é criada declarando uma
função sem um nome Para
11395 exemplo:
11396 <?php
11397 $myClosure = function () {
11398 eco 'Olá, mundo!';
11399 };
11400 $myClosure (); //Mostra "Olá mundo!"
11401 Tenha em mente que o $myClosure é uma instância do Encerramento para que você esteja
ciente do que você realmente pode fazer com ele (cf
11402 http://fr2.php.net/manual/en/class.closure.php)
11403 O caso clássico que você precisaria de um Encerramento é quando você tem que dar uma
chamada para uma função, por exemplo usort
11404 Aqui está um exemplo em que uma matriz é classificada pelo número de irmãos de cada
pessoa:
11405 <?php
11406 $data = [
11407 [
11408 'name' => 'John',
11409 'nbrOfSiblings' => 2,
11410 ]
11411 [
11412 'name' => 'Stan',
11413 'nbrOfSiblings' => 1,
11414 ]
11415 [
11416 'name' => 'Tom',
11417 'nbrOfSiblings' => 3,
11418 ]
11419 ];
11420 usort ($data, function ($e1, $e2) {
11421 if ($e1 ['nbrOfSiblings'] == $e2 ['nbrOfSiblings']) {
11422 return 0;
11423 }
11424 retornar $e1 ['nbrOfSiblings'] <$e2 ['nbrOfSiblings']? 1: 1;
11425 });
11426 var_dump ($data); //Irá mostrar Stan primeiro, depois John e finalmente Tom
11427 Seção 54.2: Usando variáveis externas
11428 É possível, dentro de um fechamento, usar uma variável externa com o uso de
palavrachave especial Por exemplo:
11429 <? php
11430 FF
11431 Notas PHP para Profissionais 285
11432 $quantidade = 1;
11433 $calculator = função ($number) use ($quantity) {
11434 devolve $number + $quantidade;
11435 };
11436 var_dump ($calculator (2)); //mostra "3"
11437 Você pode ir mais longe, criando encerramentos "dinâmicos" É possível criar uma
função que retorna um determinado
11438 calculadora, dependendo da quantidade que deseja adicionar Por exemplo:
11439 <?php
11440 function createCalculator ($quantidade) {
11441 função de retorno ($number) use ($quantity) {
11442 devolve $number + $quantidade;
11443 };
11444 }
11445 $calculator1 = createCalculator (1);
11446 $calculator2 = createCalculator (2);
11447 var_dump ($calculator1 (2)); //mostra "3"
11448 var_dump ($calculator2 (2)); //mostra "4"
11449 Seção 54.3: Ligação de fechamento básica
11450 Como visto anteriormente, um fechamento não é nada além de uma instância da classe
Closure, e diferentes métodos podem ser invocados
11451 neles Um deles é bindTo, que, dado um fechamento, retornará um novo que está
vinculado a um determinado objeto Para
11452 exemplo:
11453 <?php
11454 $myClosure = function () {
11455 echo $this> property;
11456 };
11457 classe MyClass
11458 {
11459 propriedade $pública;
11460 função pública __construct ($propertyValue)
11461 {
11462 $this> property = $propertyValue;
11463 }
11464 }
11465 $myInstance = new MyClass ('Olá, mundo!');
11466 $myBoundClosure = $myClosure> bindTo ($myInstance);
11467 $myBoundClosure (); //Mostra "Olá mundo!"
11468 Seção 54.4: Ligação de fechamento e escopo
11469 Vamos considerar este exemplo:
11470 <? php
11471 FF
11472 Notas PHP para Profissionais 286
11473 $myClosure = function () {
11474 echo $this> property;
11475 };
11476 classe MyClass
11477 {
11478 propriedade $pública;
11479 função pública __construct ($propertyValue)
11480 {
11481 $this> property = $propertyValue;
11482 }
11483 }
11484 $myInstance = new MyClass ('Olá, mundo!');
11485 $myBoundClosure = $myClosure> bindTo ($myInstance);
11486 $myBoundClosure (); //Mostra "Olá mundo!"
11487 Tente alterar a visibilidade da propriedade para protegido ou privado Você recebe um
erro fatal indicando que você não
11488 ter acesso a essa propriedade Na verdade, mesmo que o fechamento tenha sido ligado
ao objeto, o escopo em que o
11489 fechamento é invocado não é o necessário para ter esse acesso Isso é o que o segundo
argumento de bindTo é para.
11490 A única maneira de uma propriedade ser acessada se for privada é acessada de um
escopo que a permita, por exemplo a
11491 escopo da classe No exemplo de código anterior, o escopo não foi especificado, o que
significa que o fechamento
11492 foi invocado no mesmo escopo do usado quando o fechamento foi criado Vamos mudar isso:
11493 <?php
11494 $myClosure = function () {
11495 echo $this> property;
11496 };
11497 classe MyClass
11498 {
11499 propriedade $privada; //$propriedade agora é privada
11500 função pública __construct ($propertyValue)
11501 {
11502 $this> property = $propertyValue;
11503 }
11504 }
11505 $myInstance = new MyClass ('Olá, mundo!');
11506 $myBoundClosure = $myClosure> bindTo ($myInstance, MyClass :: classe);
11507 $myBoundClosure (); //Mostra "Olá mundo!"
11508 Como acabamos de dizer, se este segundo parâmetro não for usado, o encerramento é
invocado no mesmo contexto que o usado onde
11509 o fechamento foi criado Por exemplo, um fechamento criado dentro da classe de um
método que é invocado em um objeto
11510 contexto terá o mesmo escopo que o método:
11511 <?php
11512 classe MyClass
11513 {
11514 propriedade $privada;
11515 função pública __construct ($propertyValue)
11516 FF
11517 Notas PHP para Profissionais 287
11518 {
11519 $this> property = $propertyValue;
11520 }
11521 função pública getDisplayer ()
11522 {
11523 função de retorno () {
11524 echo $this> property;
11525 };
11526 }
11527 }
11528 $myInstance = new MyClass ('Olá, mundo!');
11529 $displayer = $myInstance> getDisplayer ();
11530 $displayer (); //Mostra "Olá mundo!"
11531 Seção 54.5: Ligando um encerramento para uma chamada
11532 Desde o PHP7, é possível ligar um fechamento apenas para uma chamada, graças ao
método de chamada Por exemplo:
11533 <?php
11534 classe MyClass
11535 {
11536 propriedade $privada;
11537 função pública __construct ($propertyValue)
11538 {
11539 $this> property = $propertyValue;
11540 }
11541 }
11542 $myClosure = function () {
11543 echo $this> property;
11544 };
11545 $myInstance = new MyClass ('Olá, mundo!');
11546 $myClosure> call ($myInstance); //Mostra "Olá mundo!"
11547 Ao contrário do método bindTo, não há espaço para se preocupar O escopo usado para
esta chamada é o mesmo que o
11548 um usado ao acessar ou invocar uma propriedade de $myInstance
11549 Seção 54.6: Use fechamentos para implementar o padrão do observador
11550 Em geral, um observador é uma classe com um método específico sendo chamado quando
ocorre uma ação no objeto observado
11551 Em certas situações, os encerramentos podem ser suficientes para implementar o
padrão de design do observador
11552 Aqui está um exemplo detalhado de tal implementação Primeiro vamos declarar uma
classe cujo objetivo é notificar
11553 observadores quando sua propriedade é alterada
11554 <?php
11555 classe ObservedStuff implementa SplSubject
11556 {
11557 propriedade $protegida;
11558 protected $observers = [];
11559 FF
11560 Notas PHP para Profissionais 288
11561 Anexação de função pública (SplObserver $observer)
11562 {
11563 $this> observers [] = $observador;
11564 retorne $this;
11565 }
11566 função pública desanexar (SplObserver $observer)
11567 {
11568 if (false! == $key = array_search ($observador, $this> observadores, verdadeiro)) {
11569 unset ($this> observadores [$key]);
11570 }
11571 }
11572 public function notify ()
11573 {
11574 foreach ($this> observadores como $observador) {
11575 $observer> update ($this);
11576 }
11577 }
11578 função pública getProperty ()
11579 {
11580 retornar $this> property;
11581 }
11582 função pública setProperty ($property)
11583 {
11584 $this> propriedade = $propriedade;
11585 $this> notify ();
11586 }
11587 }
11588 Então, vamos declarar a classe que representará os diferentes observadores
11589 <?php
11590 classe NamedObserver implementa SplObserver
11591 {
11592 nome $protegido;
11593 fechamento protegido $;
11594 função pública __construct (Encerramento $encerramento, $nome)
11595 {
11596 $this> closure = $closure> bindTo ($this, $this);
11597 $this> name = $name;
11598 }
11599 atualização de função pública (assunto $SplSubject)
11600 {
11601 $closure = $this> encerramento;
11602 $fechamento ($assunto);
11603 }
11604 }
11605 Vamos finalmente testar isso:
11606 <?php
11607 $o = new ObservedStuff;
11608 $observer1 = function (SplSubject $subject) {
11609 FF
11610 Notas PHP para Profissionais 289
11611 echo $this> name, 'foi notificado! Novo valor da propriedade: ', $subject>
getProperty (), "\ n";
11612 };
11613 $observer2 = function (SplSubject $subject) {
11614 echo $this> name, 'foi notificado! Novo valor da propriedade: ', $subject>
getProperty (), "\ n";
11615 };
11616 $o> attach (new NamedObserver ($observer1, 'Observer1'))
11617 > anexar (novo NamedObserver ($observer2, 'Observer2'));
11618 $o> setProperty ('Olá, mundo!');
11619 //Shows:
11620 //Observer1 foi notificado! Novo valor da propriedade: Olá, mundo!
11621 //Observer2 foi notificado! Novo valor da propriedade: Olá, mundo!
11622 Observe que este exemplo funciona porque os observadores compartilham a mesma
natureza (ambos são "observadores nomeados").
11623 FF
11624 Notas PHP para Profissionais 290
11625 Capítulo 55: Ler dados de solicitação
11626 Seção 55.1: lendo dados POST brutos
11627 Geralmente, os dados enviados em uma solicitação POST são pares chave /valor
estruturados com um tipo MIME de aplicativo /xwwwformaturlencoded
11628 No entanto, muitos aplicativos, como serviços da Web, exigem que dados brutos,
geralmente em formato XML ou JSON, sejam
11629 enviado em vez disso Esses dados podem ser lidos usando um dos dois métodos.
11630 php: //input é um fluxo que fornece acesso ao corpo da solicitação bruta
11631 $rawdata = file_get_contents ("php: //input");
11632 //Digamos que temos JSON
11633 $decoded = json_decode ($rawdata);
11634 Versão <5,6
11635 $HTTP_RAW_POST_DATA é uma variável global que contém os dados POST brutos Só está
disponível se o
11636 A diretiva always_populate_raw_post_data no php.ini está ativada
11637 $rawdata = $HTTP_RAW_POST_DATA;
11638 //Ou talvez tenhamos XML
11639 $decoded = simplexml_load_string ($rawdata);
11640 Esta variável foi preterida desde o PHP versão 5.6, e foi removida no PHP 7.0
11641 Observe que nenhum desses métodos está disponível quando o tipo de conteúdo é
definido como multipart /formdata, que é
11642 usado para uploads de arquivos
11643 Seção 55.2: Lendo dados do POST
11644 Os dados de uma solicitação POST são armazenados no superglobal $_POST na forma de
uma matriz associativa
11645 Observe que acessar um item de matriz inexistente gera um aviso, portanto a
existência deve sempre ser verificada com o
11646 funções isset () ou empty (), ou o operador coalescer nulo
11647 Exemplo:
11648 $de = isset ($_ POST ["nome"])? $_POST ["name"]: "NO NAME";
11649 $message = isset ($_ POST ["mensagem"])? $_POST ["message"]: "SEM MENSAGEM";
11650 echo "Mensagem de $de: $message";
11651 Versão = 7,0
11652 $de = $_POST ["nome"] ?? "NENHUM NOME";
11653 $message = $_POST ["message"] ?? "NENHUMA MENSAGEM";
11654 echo "Mensagem de $de: $message";
11655 Seção 55.3: Lendo dados GET
11656 Os dados de uma solicitação GET são armazenados no superglobal $_GET na forma de uma
matriz associativa
11657 Observe que acessar um item de matriz inexistente gera um aviso, portanto a
existência deve sempre ser verificada com o
11658 funções isset () ou empty (), ou o operador coalescer nulo
11659 Exemplo: (para URL /topics.php?author=alice&topic=php)
11660 FF
11661 Notas PHP para Profissionais 291
11662 $author = isset ($_ GET ["author"])? $_GET ["author"]: "NO AUTHOR";
11663 $topic = isset ($_ GET ["tópico"])? $_GET ["topic"]: "NO TÓPICO";
11664 echo "Mostrando postagens de $author sobre $topic";
11665 Versão = 7,0
11666 $author = $_GET ["author"] ?? "NENHUM AUTOR";
11667 $topic = $_GET ["tópico"] ?? "NO TÓPICO";
11668 echo "Mostrando postagens de $author sobre $topic";
11669 Seção 55.4: Manipulando erros de upload de arquivo
11670 O $_FILES ["FILE_NAME"] ['error'] (onde "FILE_NAME" é o valor do atributo name da
entrada do arquivo,
11671 presente em seu formulário) pode conter um dos seguintes valores:
11672 1 UPLOAD_ERR_OK Não há erro, o arquivo foi enviado com sucesso
11673 2 UPLOAD_ERR_INI_SIZE O arquivo enviado excede a diretiva upload_max_filesize no
arquivo php.ini
11674 3 UPLOAD_ERR_PARTIAL O arquivo enviado excede a diretiva MAX_FILE_SIZE especificada
no HTML
11675 Formato
11676 4 UPLOAD_ERR_NO_FILE Nenhum arquivo foi carregado
11677 5 UPLOAD_ERR_NO_TMP_DIR falta de uma pasta temporária (Do PHP 5.0.3).
11678 6 UPLOAD_ERR_CANT_WRITE Falha ao gravar o arquivo no disco (Do PHP 5.1.0).
11679 7 UPLOAD_ERR_EXTENSION Uma extensão PHP parou o upload do arquivo (Do PHP 5.2.0).
11680 Uma maneira básica de verificar os erros é a seguinte:
11681 <?php
11682 $fileError = $_FILES ["FILE_NAME"] ["erro"]; //onde FILE_NAME é o atributo de nome
do arquivo
11683 entrada em sua forma
11684 switch ($fileError) {
11685 case UPLOAD_ERR_INI_SIZE:
11686 //Excede o tamanho máximo em php.ini
11687 pausa;
11688 caso UPLOAD_ERR_PARTIAL:
11689 //Excede o tamanho máximo em formato html
11690 pausa;
11691 caso UPLOAD_ERR_NO_FILE:
11692 //Nenhum arquivo foi enviado
11693 pausa;
11694 caso UPLOAD_ERR_NO_TMP_DIR:
11695 //Não /tmp dir para gravar
11696 pausa;
11697 caso UPLOAD_ERR_CANT_WRITE:
11698 //Erro ao gravar no disco
11699 pausa;
11700 padrão:
11701 //Nenhum erro foi enfrentado! Ufa!
11702 pausa;
11703 }
11704 Seção 55.5: passando matrizes pelo POST
11705 Normalmente, um elemento de formulário HTML enviado para o PHP resulta em um único
valor Por exemplo:
11706 <pre>
11707 <?phpprint_r ($_ POST);
11708 </pre>
11709 FF
11710 Notas PHP para Profissionais 292
11711 <form method = "post">
11712 <input type = "hidden" name = "foo" valor = "bar" />
11713 <button type = "submit"> Enviar </button>
11714 </form>
11715 Isso resulta na seguinte saída:
11716 Matriz
11717 (
11718 [foo] => bar
11719 )
11720 No entanto, pode haver casos em que você deseja transmitir uma matriz de valores
Isso pode ser feito adicionando um PHPlike
11721 sufixo para o nome dos elementos HTML:
11722 <pre>
11723 <?phpprint_r ($_ POST);
11724 </pre>
11725 <form method = "post">
11726 <input type = "hidden" name = "foo []" valor = "bar" />
11727 <input type = "hidden" name = "foo []" valor = "baz" />
11728 <button type = "submit"> Enviar </button>
11729 </form>
11730 Isso resulta na seguinte saída:
11731 Matriz
11732 (
11733 [foo] => Matriz
11734 (
11735 [0] => bar
11736 [1] => baz
11737 )
11738 )
11739 Você também pode especificar os índices da matriz, como números ou strings:
11740 <pre>
11741 <?phpprint_r ($_ POST);
11742 </pre>
11743 <form method = "post">
11744 <input type = "hidden" name = "foo [42]" valor = "bar" />
11745 <input type = "hidden" nome = "foo [foo]" valor = "baz" />
11746 <button type = "submit"> Enviar </button>
11747 </form>
11748 Que retorna esta saída:
11749 Matriz
11750 (
11751 [foo] => Matriz
11752 (
11753 [42] => bar
11754 [foo] => baz
11755 )
11756 )
11757 FF
11758 Notas PHP para Profissionais 293
11759 Essa técnica pode ser usada para evitar loops de pósprocessamento sobre a matriz
$_POST, tornando seu código mais enxuto e
11760 mais conciso
11761 Seção 55.6: Fazendo upload de arquivos com HTTP PUT
11762 O PHP fornece suporte para o método HTTP PUT usado por alguns clientes para
armazenar arquivos em um servidor PUT pedidos são
11763 muito mais simples do que um upload de arquivo usando solicitações POST e elas se
parecem com isso:
11764 PUT /path/filename.html HTTP /1.1
11765 No seu código PHP, você faria algo assim:
11766 <?php
11767 /* Os dados PUT chegam no fluxo de stdin */
11768 $putdata = fopen ("php: //entrada", "r");
11769 /* Abra um arquivo para escrever */
11770 $fp = fopen ("putfile.ext", "w");
11771 /* Leia os dados 1 KB de cada vez
11772 e escreva no arquivo */
11773 while ($data = fread ($putdata, 1024))
11774 fwrite ($fp, $data);
11775 /* Fechar os fluxos */
11776 fclose ($fp);
11777 fclose ($putdata);
11778 ?>
11779 Também aqui você pode ler perguntas SO /respostas interessantes sobre o recebimento
de arquivos via HTTP PUT.
11780 FF
11781 Notas PHP para Profissionais 294
11782 Capítulo 56: Tipo de malabarismo e nãoestrita
11783 Questões de Comparação
11784 Seção 56.1: O que é malabarismo de tipos?
11785 PHP é uma linguagem fracamente tipada Isto significa que, por padrão, não requer
operandos em uma expressão para ser de
11786 os mesmos (ou compatíveis) tipos Por exemplo, você pode acrescentar um número a uma
string e esperar que ele funcione.
11787 var_dump ("Este é o número do exemplo" 1);
11788 A saída será:
11789 string (24) "Este é o número de exemplo 1"
11790 O PHP realiza isso ao lançar automaticamente tipos de variáveis incompatíveis em
tipos que permitem a solicitação
11791 operação a ter lugar No caso acima, ele irá converter o inteiro literal 1 em uma
string, significando que ele pode ser
11792 concatenado no literal da cadeia precedente Isso é chamado de malabarismo de tipos
Este é um recurso muito poderoso
11793 PHP, mas também é um recurso que pode te levar a puxar muito o cabelo se você não
está ciente disso, e pode até levar
11794 problemas de segurança
11795 Considere o seguinte:
11796 if (1 == $variable) {
11797 //faça alguma coisa
11798 }
11799 A intenção parece ser que o programador está verificando se uma variável tem um
valor de 1 Mas o que acontece se
11800 $variável tem um valor de "1 e meio" em vez disso? A resposta pode surpreender você.
11801 $variable = "1 e meio";
11802 var_dump (1 == $variable);
11803 O resultado é:
11804 bool (verdadeiro)
11805 Por que isso aconteceu? É porque o PHP percebeu que a string "1 e half" não é um
inteiro, mas precisa estar em
11806 para comparálo ao inteiro 1 Em vez de falhar, o PHP inicia o tipo malabarismo e
tenta converter a variável
11807 em um inteiro Ele faz isso pegando todos os caracteres no início da string que podem
ser convertidos em inteiros e
11808 lançandoos Ele pára assim que encontra um personagem que não pode ser tratado como
um número Portanto "1 e um
11809 Metade "é convertida em inteiro 1
11810 Concedido, este é um exemplo muito artificial, mas serve para demonstrar o problema
Os próximos exemplos cobrirão
11811 alguns casos em que encontrei erros causados por malabarismos de tipos que
aconteceram em software real
11812 Seção 56.2: Lendo de um arquivo
11813 Ao ler um arquivo, queremos saber quando chegamos ao final desse arquivo Sabendo que
11814 fgets () retorna false no final do arquivo, podemos usar isso como condição para um
loop No entanto, se os dados
11815 FF
11816 Notas PHP para Profissionais 295
11817 retornado da última leitura passa a ser algo que é avaliado como falso booleano,
pode causar a leitura do arquivo
11818 loop para terminar prematuramente
11819 $handle = fopen ("/caminho /para /meu /arquivo", "r");
11820 if ($handle === false) {
11821 lançar nova exceção ("Falha ao abrir arquivo para leitura");
11822 }
11823 while ($data = fgets ($handle)) {
11824 echo ("A linha do arquivo atual é $data \ n");
11825 }
11826 fclose ($handle);
11827 Se o arquivo que está sendo lido contiver uma linha em branco, o loop while será
encerrado nesse ponto, porque a string vazia
11828 é avaliado como falso booleano
11829 Em vez disso, podemos verificar o valor falso booleano explicitamente, usando
operadores de igualdade estritos:
11830 while (($data = fgets ($handle))! == false) {
11831 echo ("A linha do arquivo atual é $data \ n");
11832 }
11833 Note que este é um exemplo inventado; na vida real, usaríamos o seguinte loop:
11834 while (! feof ($handle)) {
11835 $data = fgets ($manipular);
11836 echo ("A linha do arquivo atual é $data \ n");
11837 }
11838 Ou substitua a coisa toda por:
11839 $filedata = file ("/caminho /para /meu /arquivo");
11840 foreach ($filedata as $data) {
11841 echo ("A linha do arquivo atual é $data \ n");
11842 }
11843 Seção 56.3: Trocar surpresas
11844 As instruções switch usam uma comparação não estrita para determinar
correspondências Isso pode levar a algumas surpresas desagradáveis Para
11845 Por exemplo, considere a seguinte declaração:
11846 switch ($name) {
11847 caso 'entrada 1':
11848 $mode = 'output_1';
11849 pausa;
11850 caso 'entrada 2':
11851 $mode = 'output_2';
11852 pausa;
11853 padrão:
11854 $mode = 'desconhecido';
11855 pausa;
11856 }
11857 Esta é uma instrução muito simples e funciona como esperado quando $name é uma
string, mas pode causar problemas de outra forma
11858 Por exemplo, se $nome for inteiro 0, o tipo de malabarismo acontecerá durante a
comparação No entanto, é o literal
11859 FF
11860 Notas PHP para Profissionais 296
11861 valor na instrução case que é manipulada, não a condição na instrução switch A
string "entrada 1" é
11862 convertido em inteiro 0 que corresponde ao valor de entrada do inteiro 0 O resultado
disso é se você fornecer um valor de
11863 inteiro 0, o primeiro caso é sempre executado
11864 Existem algumas soluções para este problema:
11865 Fundição explícita
11866 O valor pode ser convertido para uma string antes da comparação:
11867 switch ((string) $nome) {
11868 .
11869 }
11870 Ou uma função conhecida para retornar uma string também pode ser usada:
11871 switch (strval ($name)) {
11872 .
11873 }
11874 Ambos os métodos asseguram que o valor seja do mesmo tipo que o valor nas instruções
case
11875 Evitar interruptor
11876 O uso de uma instrução if nos fornecerá controle sobre como a comparação é feita,
permitindonos usar
11877 operadores de comparação:
11878 if ($name === "entrada 1") {
11879 $mode = "output_1";
11880 } elseif ($name === "entrada 2") {
11881 $mode = "output_2";
11882 } outro {
11883 $mode = "unknown";
11884 }
11885 Seção 56.4: Digitação estrita
11886 Desde o PHP 7.0, alguns dos efeitos prejudiciais do tipo malabarismo podem ser
mitigados com digitação rígida Ao incluir este
11887 declaração declarar como a primeira linha do arquivo, o PHP irá impor declarações de
tipo de parâmetro e tipo de retorno
11888 declarações lançando uma exceção TypeError
11889 declarar (strict_types = 1);
11890 Por exemplo, esse código, usando definições de tipo de parâmetro, lançará uma
exceção de tipo TypeError quando
11891 corre:
11892 <?php
11893 declarar (strict_types = 1);
11894 função soma (int $a, int $b) {
11895 devolve $a + $b;
11896 }
11897 soma de eco ("1", 2);
11898 Da mesma forma, esse código usa uma declaração de tipo de retorno; também lançará
uma exceção se tentar devolver qualquer outra coisa
11899 FF
11900 Notas PHP para Profissionais 297
11901 que um inteiro:
11902 <?php
11903 declarar (strict_types = 1);
11904 retornador de função ($a): int {
11905 devolve $a;
11906 }
11907 returner ("isto é uma string");
11908 FF
11909 Notas PHP para Profissionais 298
11910 Capítulo 57: Soquetes
11911 Seção 57.1: soquete do cliente TCP
11912 Criando um soquete que usa o TCP (Transmission Control Protocol)
11913 $socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
11914 Certifiquese de que o soquete foi criado com sucesso A função onSocketFailure vem de
manipular erros de soquete
11915 exemplo neste tópico
11916 if (! is_resource ($socket)) onSocketFailure ("Falha ao criar soquete");
11917 Conecte o soquete a um endereço especificado
11918 A segunda linha falha normalmente se a conexão falhar
11919 socket_connect ($socket, "chat.stackoverflow.com", 6667)
11920 ou onSocketFailure ("Falha ao conectarse ao chat.stackoverflow.com:6667", $socket);
11921 Enviando dados para o servidor
11922 A função socket_write envia bytes por meio de um soquete No PHP, uma matriz de bytes
é representada por uma string, que é
11923 normalmente insensível à codificação
11924 socket_write ($socket, "NICK Alice \ r \ nUSER alice 0 *: Alice \ r \ n");
11925 Recebendo dados do servidor
11926 O snippet a seguir recebe alguns dados do servidor usando a função socket_read
11927 Passando PHP_NORMAL_READ como o terceiro parâmetro lê até um byte \ r /\ n, e este
byte é incluído no retorno
11928 valor
11929 Passar PHP_BINARY_READ, pelo contrário, lê a quantidade necessária de dados do fluxo
11930 Se socket_set_nonblock foi chamado antes, e PHP_BINARY_READ é usado, socket_read
retornará false
11931 imediatamente Caso contrário, o método bloqueia até que dados suficientes (para
alcançar o comprimento no segundo parâmetro, ou para
11932 chegar a um final de linha) são recebidos, ou o socket é fechado
11933 Este exemplo lê dados de um servidor supostamente IRC
11934 while (true) {
11935 //lê uma linha do soquete
11936 $line = socket_read ($socket, 1024, PHP_NORMAL_READ);
11937 if (substr ($line, 1) === "\ r") {
11938 //ler /pular um byte do soquete
11939 //assumimos que o próximo byte no fluxo deve ser um \ n
11940 //isso é realmente ruim na prática; o script é vulnerável a valores inesperados
11941 socket_read ($socket, 1, PHP_BINARY_READ);
11942 }
11943 $message = parseLine ($line);
11944 if ($message> type === "QUIT") quebra;
11945 }
11946 Fechando a tomada
11947 Fechar o soquete libera o soquete e seus recursos associados.
11948 FF
11949 Notas PHP para Profissionais 299
11950 socket_close ($socket);
11951 Seção 57.2: soquete do servidor TCP
11952 Criação de soquete
11953 Crie um soquete que use o TCP É o mesmo que criar um soquete de cliente.
11954 $socket = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
11955 Ligação de soquete
11956 Ligações de ligação de uma determinada rede (parâmetro 2) para uma porta específica
(parâmetro 3) para o socket
11957 O segundo parâmetro é geralmente "0.0.0.0", que aceita conexão de todas as redes
Também pode
11958 Uma causa comum de erros do socket_bind é que o endereço especificado já está
vinculado a outro processo
11959 Outros processos são geralmente mortos (geralmente manualmente para evitar a morte
acidental de processos críticos) para que
11960 soquetes seriam liberados
11961 socket_bind ($socket, "0.0.0.0", 6667) ou onSocketFailure ("Falha ao ligar a
0.0.0.0:6667");
11962 Definir um soquete para ouvir
11963 Faça o soquete escutar conexões de entrada usando socket_listen O segundo parâmetro
é o máximo
11964 número de conexões para permitir filas antes de serem aceitas
11965 socket_listen ($socket, 5);
11966 Manipulando conexão
11967 Um servidor TCP é na verdade um servidor que lida com conexões filhas O
socket_accept cria uma nova conexão filho.
11968 $conn = socket_accept ($socket);
11969 A transferência de dados para uma conexão de socket_accept é a mesma que para um
soquete de cliente TCP
11970 Quando esta conexão deve ser fechada, chame socket_close ($conn); diretamente Isso
não afetará o TCP original
11971 soquete do servidor
11972 Fechando o servidor
11973 Por outro lado, socket_close ($socket); deve ser chamado quando o servidor não for
mais usado Isso liberará o
11974 Endereço TCP também, permitindo que outros processos se liguem ao endereço
11975 Seção 57.3: soquete do servidor UDP
11976 Um servidor UDP (protocolo de datagrama de usuário), diferente do TCP, não é baseado
em fluxo É baseado em pacotes, ou seja, um cliente envia dados em
11977 unidades chamadas "pacotes" para o servidor, e o cliente identifica os clientes pelo
seu endereço Não há nenhuma função interna que
11978 relaciona diferentes pacotes enviados do mesmo cliente (ao contrário do TCP, onde os
dados do mesmo cliente são manipulados por um
11979 recurso específico criado por socket_accept) Pode ser pensado como uma nova conexão
TCP é aceita e fechada
11980 toda vez que um pacote UDP chega
11981 Criando um soquete do servidor UDP
11982 $socket = socket_create (AF_INET, SOCK_DGRAM, SOL_UDP);
11983 Vinculando um soquete a um endereço
11984 FF
11985 Notas PHP para Profissionais 300
11986 Os parâmetros são os mesmos que para um servidor TCP
11987 socket_bind ($socket, "0.0.0.0", 9000) ou onSocketFailure ("Falha ao ligar a
0.0.0.0:9000",
11988 $socket);
11989 Enviando um pacote
11990 Esta linha envia $dados em um pacote UDP para $address: $port
11991 socket_sendto ($socket, $data, strlen (dados $), 0, $endereço, $port);
11992 Recebendo um pacote
11993 O snippet a seguir tenta gerenciar pacotes UDP de maneira indexada pelo cliente
11994 $clients = [];
11995 while (true) {
11996 socket_recvfrom ($socket, $buffer, 32768, 0, $ip, $port) === verdadeiro
11997 ou onSocketFailure ("Falha ao receber pacote", $socket);
11998 $address = "$ip: $port";
11999 if (! isset ($clientes [$endereço])) $clientes [$endereço] = novo Cliente ();
12000 $clientes [$endereço] > handlePacket ($buffer);
12001 }
12002 Fechando o servidor
12003 socket_close pode ser usado no recurso de soquete do servidor UDP Isso liberará o
endereço UDP, permitindo que outros
12004 processos para ligar a este endereço
12005 Seção 57.4: Manipulando erros de soquete
12006 socket_last_error pode ser usado para obter o ID de erro do último erro da extensão
de sockets
12007 O socket_strerror pode ser usado para converter o ID em strings legíveis por humanos
12008 function onSocketFailure (string $mensagem, $soquete = nulo) {
12009 if (is_resource ($socket)) {
12010 $message = ":" socket_strerror (socket_last_error ($socket));
12011 }
12012 morrer (mensagem $);
12013 }
12014 FF
12015 Notas PHP para Profissionais 301
12016 Capítulo 58: DOP
12017 A extensão PDO (PHP Data Objects) permite aos desenvolvedores conectarse a vários
tipos diferentes de bancos de dados e
12018 executar consultas contra eles de maneira uniforme e orientada a objetos
12019 Seção 58.1: Prevenindo injeção de SQL com parâmetros
12020 Consultas
12021 A injeção de SQL é um tipo de ataque que permite que um usuário malintencionado
modifique a consulta SQL, adicionando comandos indesejados
12022 para isso Por exemplo, o código a seguir é vulnerável:
12023 //Não use este código vulnerável!
12024 $sql = 'SELECT nome, email, user_level FROM usuários WHERE userID =' $_GET
['usuário'];
12025 $conn> query ($sql);
12026 Isso permite que qualquer usuário deste script modifique nosso banco de dados
basicamente à vontade Por exemplo, considere a seguinte consulta
12027 corda:
12028 page.php? user = 0;% 20TRUNCATE% 20TABLE% 20users;
12029 Isso torna nossa consulta de exemplo semelhante a esta
12030 SELECT nome, email, user_level FROM usuários WHERE userID = 0; Usuários TRUNCATE
TABLE;
12031 Embora este seja um exemplo extremo (a maioria dos ataques de injeção SQL não tem
como objetivo excluir dados, nem a maioria das consultas PHP
12032 funções de execução suportam multiquery), este é um exemplo de como um ataque de
injeção SQL pode ser
12033 a montagem descuidada da consulta Infelizmente, ataques como este são muito comuns e
são altamente eficazes devido a
12034 codificadores que não tomam as devidas precauções para proteger seus dados
12035 Para impedir que a injeção de SQL ocorra, as instruções preparadas são a solução
recomendada Ao invés de
12036 Ao concatenar os dados do usuário diretamente à consulta, é usado um marcador de
posição Os dados são então enviados separadamente,
12037 significa que não há chance de o mecanismo SQL confundir os dados do usuário para um
conjunto de instruções
12038 Embora o tópico aqui seja PDO, observe que a extensão PHP MySQLi também suporta
preparações
12039 afirmações
12040 O PDO suporta dois tipos de espaços reservados (espaços reservados não podem ser
usados para nomes de colunas ou tabelas, apenas valores):
12041 1 Espaços reservados nomeados Dois pontos (:), seguidos de um nome distinto (por
exemplo: usuário)
12042 //usando espaços reservados nomeados
12043 $sql = 'SELECT nome, email, user_level FROM usuários WHERE userID =: user';
12044 $prep = $conn> prepare ($sql);
12045 $prep> execute (['usuário' => $_GET ['usuário']]); //array associativo
12046 $result = $prep> fetchAll ();
12047 2 Espaços de posicionamento posicionais SQL tradicionais, representados como?:
12048 //usando marcadores de ponto de interrogação
12049 $sql = 'SELECT nome, user_level FROM usuários WHERE userID =? AND user_level =? ';
12050 $prep = $conn> prepare ($sql);
12051 $prep> execute ([$_ GET ['usuário'], $_GET ['user_level']]); //matriz indexada
12052 FF
12053 Notas PHP para Profissionais 302
12054 $result = $prep> fetchAll ();
12055 Se alguma vez você precisar alterar dinamicamente os nomes de tabelas ou colunas,
saiba que isso é devido aos seus próprios riscos de segurança e
12056 má prática Porém, isso pode ser feito por concatenação de strings Uma maneira de
melhorar a segurança de tais consultas é definir
12057 uma tabela de valores permitidos e compare o valor que você deseja concatenar nesta
tabela
12058 Esteja ciente de que é importante definir o conjunto de caracteres de conexão
somente por DSN; caso contrário, sua
12059 propenso a uma vulnerabilidade obscura se alguma codificação ímpar for usada Para
versões PDO anteriores à configuração 5.3.6 charset
12060 por meio de DSN não está disponível e, portanto, a única opção é definir o atributo
PDO :: ATTR_EMULATE_PREPARES como falso em
12061 a conexão logo após ser criada
12062 $conn> setAttribute (PDO :: ATTR_EMULATE_PREPARES, false);
12063 Isso faz com que o PDO use as instruções preparadas nativas do DBMS subjacente em
vez de apenas emulálas
12064 No entanto, esteja ciente de que o PDO fará fallback silencioso para emular
instruções que o MySQL não pode preparar nativamente:
12065 aqueles que podem estão listados no manual (fonte)
12066 Seção 58.2: Conexão e Recuperação Básica do PDO
12067 Desde o PHP 5.0, o PDO está disponível como uma camada de acesso ao banco de dados É
independente do banco de dados, e assim o seguinte
12068 O código de exemplo de conexão deve funcionar para qualquer um dos bancos de dados
suportados simplesmente alterando o DSN
12069 //Primeiro, crie o identificador do banco de dados
12070 //Usando o MySQL (conexão via socket local):
12071 $dsn = "mysql: host = localhost; dbname = testedb; charset = utf8";
12072 //Usando o MySQL (conexão via rede, opcionalmente você pode especificar a porta
também):
12073 //$dsn = "mysql: host = 127.0.0.1; porta = 3306; dbname = testdb; charset = utf8";
12074 //ou postgres
12075 //$dsn = "pgsql: host = localhost; porta = 5432; dbname = testdb;";
12076 //Ou até mesmo SQLite
12077 //$dsn = "sqlite: /path /to /database"
12078 $username = "usuário";
12079 $password = "pass";
12080 $db = novo PDO ($dsn, $username, $password);
12081 //configura o PDO para lançar uma exceção se uma consulta inválida for fornecida
12082 $db> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);
12083 //Em seguida, vamos preparar uma instrução para execução, com um único espaço
reservado
12084 $query = "SELECT * FROM usuários WHERE class =?";
12085 $statement = $db> prepare ($query);
12086 //Cria alguns parâmetros para preencher os espaços reservados e executa a declaração
12087 $parameters = ["221B"];
12088 $statement> execute ($parameters);
12089 //Agora, percorra cada registro como uma matriz associativa
12090 while ($row = $instrução> busca (PDO :: FETCH_ASSOC)) {
12091 do_stuff ($row);
12092 }
12093 FF
12094 Notas PHP para Profissionais 303
12095 A função prepare cria um objeto PDOStatement da string de consulta A execução da
consulta e recuperação
12096 dos resultados são realizados neste objeto retornado Em caso de falha, a função
retorna false ou lança
12097 uma exceção (dependendo de como a conexão do PDO foi configurada)
12098 Seção 58.3: Transações do banco de dados com o PDO
12099 As transações de banco de dados garantem que um conjunto de alterações de dados só
se tornará permanente se cada instrução for
12100 bem sucedido Qualquer falha de consulta ou código durante uma transação pode ser
detectada e, em seguida, você tem a opção de reverter
12101 as tentativas de mudanças
12102 O PDO fornece métodos simples para iniciar, confirmar e reverter transações
12103 $pdo = novo PDO (
12104 $dsn,
12105 $username,
12106 $senha
12107 matriz (PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION)
12108 );
12109 experimentar {
12110 $statement = $pdo> prepare ("UPDATE usuário SET nome =: nome");
12111 $pdo> beginTransaction ();
12112 $statement> execute (["nome" => 'Bob']);
12113 $statement> execute (["nome" => 'Joe']);
12114 $pdo> commit ();
12115 }
12116 catch (\ Exception $e) {
12117 if ($pdo> inTransaction ()) {
12118 $pdo> rollback ();
12119 //Se chegamos aqui, nossas duas atualizações de dados não estão no banco de dados
12120 }
12121 jogar $e;
12122 }
12123 Durante uma transação, quaisquer alterações de dados feitas são visíveis apenas para
a conexão ativa Instruções SELECT retornarão
12124 as alterações alteradas, mesmo que ainda não estejam comprometidas com o banco de
dados
12125 Nota: Consulte a documentação do fornecedor de banco de dados para obter detalhes
sobre o suporte a transações Alguns sistemas não suportam
12126 transações em tudo Alguns suportam transações aninhadas enquanto outros não.
12127 Exemplo prático usando transações com PDO
12128 Na seção a seguir é demonstrado um exemplo prático do mundo real, onde o uso de
transações garante a
12129 consistência do banco de dados
12130 Imagine o seguinte cenário, digamos que você está construindo um carrinho de compras
para um site de comércio eletrônico e você
12131 decidiu manter os pedidos em duas tabelas de banco de dados Um nome de ordens com os
campos order_id, nome, endereço,
12132 telefone e created_at E um segundo chamado orders_products com os campos order_id,
product_id e
12133 quantidade A primeira tabela contém os metadados da ordem, enquanto a segunda contém
os produtos reais que têm
12134 foi encomendado
12135 Inserindo um novo pedido no banco de dados
12136 Para inserir um novo pedido no banco de dados, você precisa fazer duas coisas
Primeiro você precisa inserir um novo registro dentro do
12137 FF
12138 Notas PHP para Profissionais 304
12139 tabela de pedidos que conterá os metadados do pedido (nome, endereço, etc) E então
você precisa inserir um
12140 registro na tabela orders_products, para cada um dos produtos incluídos no pedido
12141 Você poderia fazer isso fazendo algo semelhante ao seguinte:
12142 //Insira os metadados do pedido no banco de dados
12143 $preparedStatement = $db> prepare (
12144 'INSERT INTO `orders` (` nome`, `endereço`,` telefone`, `criado_at`)
12145 VALORES (: nome, endereço, telefone,: created_at)
12146 );
12147 $preparedStatement> execute ([
12148 'name' => $name,
12149 'endereço' => $endereço,
12150 'telefone' => $telefone,
12151 'created_at' => time (),
12152 ]);
12153 //Obter o `order_id` gerado
12154 $orderId = $db> lastInsertId ();
12155 //Construir a consulta para inserir os produtos do pedido
12156 $insertProductsQuery = 'INSERT INTO `orders_products` (` order_id`, `product_id`,`
quantidade`)
12157 VALORES ';
12158 $count = 0;
12159 foreach ($products as $productId => $quantity) {
12160 $insertProductsQuery = '(: order_id' $count ',: product_id' $count ',: quantidade'
12161 $count ')';
12162 $insertProductsParams ['order_id' $count] = $orderId;
12163 $insertProductsParams ['product_id' $count] = $productId;
12164 $insertProductsParams ['quantity' $count] = $quantidade;
12165 ++ $count;
12166 }
12167 //Insere os produtos incluídos no pedido no banco de dados
12168 $preparedStatement = $db> prepare ($insertProductsQuery);
12169 $preparedStatement> execute ($insertProductsParams);
12170 Isso funcionará muito bem para inserir um novo pedido no banco de dados, até que
algo inesperado aconteça e para alguns
12171 razão pela qual a segunda consulta INSERT falha Se isso acontecer, você receberá um
novo pedido dentro da tabela de pedidos.
12172 que não terá produtos associados a ele Felizmente, a correção é muito simples, tudo
o que você precisa fazer é
12173 consultas na forma de uma única transação de banco de dados
12174 Inserindo um novo pedido no banco de dados com uma transação
12175 Para iniciar uma transação usando PDO, tudo o que você precisa fazer é chamar o
método beginTransaction antes de executar qualquer
12176 consultas ao seu banco de dados Em seguida, você faz as alterações desejadas nos
dados, executando INSERT e /ou UPDATE
12177 consultas E, finalmente, você chama o método commit do objeto PDO para tornar as
alterações permanentes Até você ligar para o
12178 método commit, todas as mudanças que você fez em seus dados até este momento ainda
não são permanentes e podem ser facilmente
12179 revertido simplesmente chamando o método de reversão do objeto PDO
12180 No exemplo a seguir, é demonstrado o uso de transações para inserir um novo pedido
no banco de dados,
12181 garantindo ao mesmo tempo a consistência dos dados Se uma das duas consultas falhar,
todas as alterações serão
12182 revertido.
12183 FF
12184 Notas PHP para Profissionais 305
12185 //Neste exemplo, estamos usando o MySQL, mas isso se aplica a qualquer banco de
dados que tenha suporte para
12186 transações
12187 $db = new PDO ('mysql: host =' $host '; dbname =' $dbname '; charset = utf8',
$username,
12188 $password);
12189 //Certifiquese de que o PDO lance uma exceção em caso de erro para facilitar o
tratamento de erros
12190 $db> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);
12191 experimentar {
12192 //A partir deste ponto e até que a transação esteja sendo confirmada, todas as
mudanças no banco de dados
12193 ser revertido
12194 $db> beginTransaction ();
12195 //Insira os metadados do pedido no banco de dados
12196 $preparedStatement = $db> prepare (
12197 'INSERT INTO `orders` (` order_id`, `nome`,` endereço`, `created_at`)
12198 VALORES (: nome, endereço, telefone,: created_at)
12199 );
12200 $preparedStatement> execute ([
12201 'name' => $name,
12202 'endereço' => $endereço,
12203 'telefone' => $telefone,
12204 'created_at' => time (),
12205 ]);
12206 //Obter o `order_id` gerado
12207 $orderId = $db> lastInsertId ();
12208 //Construir a consulta para inserir os produtos do pedido
12209 $insertProductsQuery = 'INSERT INTO `orders_products` (` order_id`, `product_id`,`
quantidade`)
12210 VALORES ';
12211 $count = 0;
12212 foreach ($products as $productId => $quantity) {
12213 $insertProductsQuery = '(: order_id' $count ',: product_id' $count ',: quantidade'
12214 $count ')';
12215 $insertProductsParams ['order_id' $count] = $orderId;
12216 $insertProductsParams ['product_id' $count] = $productId;
12217 $insertProductsParams ['quantity' $count] = $quantidade;
12218 ++ $count;
12219 }
12220 //Insere os produtos incluídos no pedido no banco de dados
12221 $preparedStatement = $db> prepare ($insertProductsQuery);
12222 $preparedStatement> execute ($insertProductsParams);
12223 //Faça as mudanças no banco de dados permanente
12224 $db> commit ();
12225 }
12226 catch (PDOException $e) {
12227 //Falha ao inserir o pedido no banco de dados para que possamos reverter quaisquer
alterações
12228 $db> rollback ();
12229 jogar $e;
12230 }
12231 Seção 58.4: PDO: conectandose ao servidor MySQL /MariaDB
12232 Existem duas maneiras de se conectar a um servidor MySQL /MariaDB, dependendo da sua
infraestrutura.
12233 FF
12234 Notas PHP para Profissionais 306
12235 Conexão padrão (TCP /IP)
12236 $dsn = 'mysql: dbname = demo; host = servidor; porta = 3306; charset = utf8';
12237 $connection = new \ PDO ($dsn, $username, $password);
12238 //lança exceções, quando o erro de SQL é causado
12239 $connection> setAttribute (\ PDO :: ATTR_ERRMODE, \ PDO :: ERRMODE_EXCEPTION);
12240 //impede a emulação de declarações preparadas
12241 $connection> setAttribute (\ PDO :: ATTR_EMULATE_PREPARES, false);
12242 Como o PDO foi projetado para ser compatível com versões antigas de servidores MySQL
(que não tinham suporte para
12243 instruções preparadas), você deve desabilitar explicitamente a emulação Caso
contrário, você perderá a injeção adicionada
12244 benefícios de prevenção, que geralmente são concedidos usando declarações preparadas
12245 Outro compromisso de design, que você deve ter em mente, é o comportamento padrão de
tratamento de erros Caso contrário
12246 configurado, o PDO não mostrará qualquer indicação de erros de SQL
12247 É altamente recomendável configurálo para "modo de exceção", porque isso ganha
funcionalidade adicional, quando
12248 escrevendo abstrações de persistência (por exemplo: tendo uma exceção, ao violar a
restrição UNIQUE)
12249 Conexão soquete
12250 $dsn = 'mysql: unix_socket = /tmp /mysql.sock; dbname = demo; charset = utf8';
12251 $connection = new \ PDO ($dsn, $username, $password);
12252 //lança exceções, quando o erro de SQL é causado
12253 $connection> setAttribute (\ PDO :: ATTR_ERRMODE, \ PDO :: ERRMODE_EXCEPTION);
12254 //impede a emulação de declarações preparadas
12255 $connection> setAttribute (\ PDO :: ATTR_EMULATE_PREPARES, false);
12256 Em sistemas semelhantes a unix, se o nome do host for 'localhost', a conexão com o
servidor será feita por meio de um domínio
12257 soquete
12258 Seção 58.5: PDO: Obter número de linhas afetadas por uma consulta
12259 Começamos com $db, uma instância da classe PDO Depois de executar uma consulta,
muitas vezes queremos determinar o número
12260 de linhas que foram afetadas por ele O método rowCount () do PDOStatement funcionará
bem:
12261 $query = $db> query ("DELETE DA TABELA WHERE nome = 'John'"); $count = $query>
rowCount (); echo "Excluído
12262 linhas de $count chamadas John ";
12263 NOTA: Este método só deve ser usado para determinar o número de linhas afetadas por
INSERT, DELETE e UPDATE
12264 afirmações Embora esse método também funcione para instruções SELECT, ele não é
consistente em todos os bancos de dados.
12265 Seção 58.6: PDO :: lastInsertId ()
12266 Você pode frequentemente achar a necessidade de obter o valor da ID incrementada
automaticamente para uma linha que acabou de inserir na sua conta
12267 tabela de banco de dados Você pode conseguir isso com o método lastInsertId ().

Anda mungkin juga menyukai