[Powered by Google Translate] [Sección 8 - máis cómodo] [Rob Bowden - Harvard University] [Esta é CS50. - CS50.TV] Estas notas de sección semanas van ser moi curto, entón eu só vou continuar a falar, vostedes van continuar a facer preguntas, e imos tratar encher o tempo, tanto como sexa posible. Moita xente pensa que este pset non é necesariamente difícil, pero é moi longo. A especificación pset si leva unha hora para ler. Nós dámoslle unha morea de SQL que podería posiblemente necesidade de usar. Nos leva-lo a través de unha chea de que, por iso non debe ser moi malo. Alguén xa comezou ou rematou? É o pset pasado. Oh, meu Deus. Normalmente hai un JavaScript un despois, pero as cousas cambian calendario fai todo unha semana máis curta, e non temos un pset JavaScript. Eu non sei como iso afecta o JavaScript está indo a aparecer no exame ou Cuestionario 1. Imaxino que será algo así como que precisa saber cousas de alto nivel sobre JavaScript pero dubido que acabara de darlle directamente o código JavaScript xa que non tiña un pset nel. Pero iso vai ser o material para a súa análise proba a próxima semana. Sección de preguntas. Unha gran cantidade deste material é un pouco mal formulada, pero imos discutir por que. Ao contrario de C, PHP é unha "dinamicamente tipada" lingua. O que isto significa, lle pregunta? Ben, diga adeus a todos aqueles float, char, int e outras palabras clave que necesita para utilizar ao declarar variables e funcións en C. No PHP, tipo dunha variable é determinado polo valor que está detén. Así, antes de escribir este código nun arquivo chamado dynamic.php, PHP é dinámicamente ingresaran. Iso é verdade. Eu desacordo co feito de que iso significa que estamos dicindo adeus a char, int, float, e outras palabras clave. A diferenza exacta entre tipagem dinámica e alternativa, que é ingresaran estaticamente, que tipagem dinámica, toda a súa comprobación de tipo e material acontece en tempo de execución, mentres que tipagem estática acontece en tempo de compilación. A palabra estática en xeral parece significar cousas tempo de compilación. Coido que existen outros usos para el, pero en C cando declara unha variable estática, seu almacenamento é alocado en tempo de compilación. Aquí, tipagem dinámica significa só que - C, se tentar engadir unha cadea e un enteiro, cando compilar, vai reclamar, porque vai dicir que non pode engadir un int e un punteiro. Non é só unha operación válida. Esa é outra cousa que nós imos chegar a un segundo. Pero este tipo de verificación, o feito de que se queixa en tempo de compilación, é a comprobación de tipo estático. Hai linguas que non precisa dicir float, char, int, e todas esas cousas, pero a linguaxe pode dicir a partir do contexto da cousa que tipo que se quere que sexa, pero aínda tipagem estática. Entón, se tomar 51, OCaml, nunca precisa utilizar calquera destes tipos, pero aínda vai a tempo de compilación dicir que non pode facer iso porque está mesturando un int e unha corda. Dinámicamente ingresaran só significa que nalgún momento durante o tempo de execución que está indo para obter unha reclamación. Se tamén usado Java antes de, en xeral, case todas as linguas do tipo C vai ser ingresaran estaticamente, para C, C + +, Java, todos estes son xeralmente ingresaran estaticamente. En Java, cando compilar algo e está dicindo cadea s equivale a algo novo que non é unha cadea, que vai reclamar porque eses tipos simplemente non combinan. Que vai reclamar en tempo de compilación. Pero el tamén ten un tempo dinámica cousas como se tentar publicar algunha cousa para un tipo que é máis específico que o seu tipo de corrente, non hai nada que pode facer en tempo de compilación para comprobar que o elenco está indo a ter éxito. Java tamén ten algún tipo dinámico comprobar que, logo que se chega a esta liña de código cando é, en realidade, a execución, que vai facer o reparto, comprobar se aquel elenco era válido, en primeiro lugar, e se non está, entón vai reclamar que ten un tipo incorrecto. Tipo dinámico verificación. Escriba isto nun arquivo chamado dynamic.php. Dynamic.php. Vou descomprimir que o formato. Temos unha variable, estableza o enteiro 7, entón imos imprimir lo e s% - Ah, estamos imprimindo tipo del, de xeito gettype vai voltar tipo de variable. Estamos só a impresión do tipo de unha e outra vez. Nós só php.dynamic.php. Imos ver o que cambia de completo cadea para Boolean coma nós pasamos. En C non hai ningún tipo de datos Boolean, non hai tipo de datos. Hai char * e Boolean só tende a ser int ou char ou algo así. No PHP estes tipos non existen, e iso é unha das grandes vantaxes do PHP sobre C - secuencia de operacións que son infinitamente máis fácil do que en PHP C. Eles só traballar. Así, volvemos aquí. Corremos dynamic.php. Isto di o intérprete PHP, chamado php, para executar o código PHP en dynamic.php. Se ten calquera erro no ficheiro, o intérprete pode dicir-lle! O intérprete, esta é outra gran diferenza entre PHP e C. C ten que compilar algo logo executar o arquivo compilado. No PHP nunca compilar nada. Así, o intérprete de PHP é, basicamente, só lendo esta liña por liña. Chega var = 7, a continuación, ela atinxe printf entón chega var entón chega printf e así por diante. Hai un pouco de compilar que fai, e almacena en caché os resultados por iso, se executar o script máis tarde pode facer algúns, pero basicamente é unha liña por liña tipo de cousas. Isto significa que unha morea de optimizacións que nós comezamos en C, como a compilación, é só xeralmente o compilador pode facer unha chea de trucos para ti. Pode aproveitar as variables utilizadas, pode facer todos eses tipos de cousas, pode facer recursão de cola. No PHP non está indo para obter esa vantaxe porque só vai comezar a executar liña por liña por liña, e realmente non recoñecer esas cousas tan facilmente xa que non é un paso de compilación de gran sobre a cousa e, a continuación, a execución; é só liña por liña. Entón ese é o intérprete. Voltar á nosa tipagem dinámica: moi legal, ne? Vostede definitivamente non podería facelo en C! Agora, vexa se pode descubrir o tipo de cada un dos seguintes valores. Vexa este a referencia. Entón, 3,50. Que tipo pensas que vai ser? Aquí están os tipos que temos. Temos bools, enteiros, puntos flotantes, cadeas, arrays, obxectos, e recursos, que é unha especie de vaga. Eu creo que hai, en realidade, un exemplo aquí. Entón hai NULL. NULL é un tipo especial. Ao contrario de C onde NULL é só un punteiro co enderezo 0, en PHP, NULL é o seu propio tipo, onde o único válido de que tipo é NULL. Isto é moito máis útil para comprobación de erros. C, onde tivemos esta cuestión onde se voltar NULL, iso significa que está retornando un punteiro NULL ou usar NULL para indicar erro ou toda esa confusión que tivo nun punto. Aquí, retornando NULL xeralmente significa erro. Unha morea de cousas tamén retornar false para erro. Pero o punto é o tipo NULL, o único do tipo NULL é NULL. Entón callback é como pode definir algunhas funcións anónimas. Non ten que dar a función dun nome, pero non terá que tratar con isto aquí. Mirando para os tipos que eles esperan que a xente sabe, ¿Que pensas do tipo de 3,50 é? >> [Alumno] Float. Si Entón aquí, o que pensas do tipo de que é iso? >> [Alumno] Array. Si A primeira foi a boia, a segunda é unha matriz. Teña en conta que esta matriz non é como unha matriz C onde ten índice 0 ten algún valor, índice 1 ten algún valor. Aquí, os índices son A, B, e C, e os valores son 1, 2, e 3. No PHP, non hai diferenza entre unha matriz asociativa e só unha matriz común como sería de pensar niso en C. Non é só iso, e baixo o capó dunha matriz regular é só unha matriz asociativa onde 0 mapas para algún valor da mesma maneira unha mapas para algún valor. Por este motivo, o PHP pode ser moi malo para realmente rápidos / code aferição cousas xa que en C, cando está usando unha matriz que vostede sabe que o acceso a un membro é tempo constante. No PHP accedendo un membro é quen sabe canto tempo? Probablemente é constante se hashes correctamente. Quen sabe o que está realmente facendo debaixo do capo? Vostede realmente precisa de ollar para a implementación para ver como vai tratar con isto. Entón fopen. Eu creo que aquí imos só PHP fopen manual para ollar para o tipo de retorno. Vemos aquí que pode mirar para arriba practicamente calquera función na guía de PHP e este é o tipo de home á páxina de PHP. O tipo de retorno vai ser de recursos. É por iso que eu olhei para arriba, porque realmente non definir recursos. A idea de recurso, en C ten un tipo de ficheiro * ou o que quere; en PHP recurso é o seu arquivo *. É o que vai estar lendo, é o que vai ser escribindo. É xeralmente externo, por iso é un recurso que pode tirar cousas e tirar cousas para. E, finalmente, cal é o tipo de NULL? >> [Alumno] NULL. Si Entón a única cousa que é NULL se NULL. NULL é NULL. Unha característica do sistema PHP tipo (para mellor ou para peor) é a súa capacidade de facer malabarismos tipos. Cando escribir unha liña de código PHP que combina valores de diferentes tipos, PHP vai facer as cousas corda. Proba cada unha das seguintes liñas de código PHP. O que está impreso? É o que esperaba? Por que ou por que non? Este feito sobre o PHP é o que fai o que chamamos feblemente tipada. Feblemente ingresaran e rixidez, hai usos diferentes para estes termos, pero a maioría das persoas usan feblemente ingresaran e rixidez para dicir este tipo de cousas onde ("1" + 2), que funciona. C que non ía funcionar. Podes imaxinar iso non funciona. Unha morea de xente mesturar tipagem dinámica e tipagem feble e tipagem estática e tipagem forte. Python é outro exemplo dunha linguaxe que é dinámicamente ingresaran. Pode xogar en torno a tipos de variables e que vai determinar en tempo de execución os controis de erro. En Python vai executar iso e vai ver ("1" + 2); e iso vai fallar porque el di que non pode engadir unha cadea e un enteiro. No PHP, que é tan tipagem dinámica, iso non vai fallar. Tipagem feble ten que ver co feito de que fai cousas co tipo que realmente non ten sentido necesariamente. Entón ("1" + 2), podo imaxinar que ser o de 12 cordas, podo imaxinar que sexa a secuencia de tres, Podo imaxinar que sexa o 3 enteiro. Non é necesariamente ben definido, e probablemente imos ver aquí que cando imprimir ("1" + 2), que probablemente vai acabar por ser diferente de impresión (1 + "2"). E iso tende a ser, na miña opinión, a peor. Aquí podemos probar estes. Outro truco pouco sobre PHP é que non precisa realmente gravar o ficheiro. El ten de executar este modo de mando. Entón php-r, entón podemos xogar no mando aquí: "Imprimir ('1 '+ 2);" e eu vou publicar unha nova liña. Este impreso 3. Parece que imprime 3 e é o 3 enteiro. Entón, agora imos tratar o contrario: "Imprimir (1 + 2"); Temos 3, e iso tamén vai ser enteiro 3? Sinceramente, non teño idea. Parece que é consistente. Nunca hai ningunha oportunidade de el ser o 12 cordas ou algo así porque o PHP, ao contrario de JavaScript e Java tamén, ten un operador separado para concatenação. Concatenação en PHP é punto. Así, a impresión (1 '2 '.) Vai dar-nos 12. Iso tende a levar a unha confusión onde as persoas tentan facer algo como str + = algunha outra cousa que eles queren engadir ao final da súa corda, e que vai fallar. Cómpre facer str. = Entón non se esqueza de concatenação en PHP é un punto. Outras cousas para intentar: Imprimir ("CS" + 50); Eu xa lle dixen que non hai esperanza de que isto resulte en CS50 sempre que non é a concatenação +. ¿Que pensas que iso vai acabar sendo? Eu sinceramente non teño absolutamente ningunha idea. Parece que é só 50. El ve a corda, e eu aposto que se colocarmos 123CS - El ve a primeira corda, el tenta ler un número enteiro de que ou un número a partir del. Neste caso, ve 123CS. "Isto non ten sentido como un número enteiro, entón eu só vou pensar en 123." Entón 123 + 50 vai ser 173. E aquí comeza a ler isto como un número enteiro. Non ve nada, por iso só trata como 0. Entón 0 + 50 vai ser 50. Isto que estou supondo que vai facer algo semellante. Estou pensando 99. Si, porque vai tomar a primeira - Entón, 99. Aquí (10/7), se este fose C, o que tería que volver? [Estudante] 1. >> Si, sería un dato que 10/7 é dividir números enteiros 2. Un enteiro dividido por un número enteiro vai voltar un enteiro. Non pode voltar un calquera punto que sería, por iso só vai voltar 1. Aquí impresión (10/7), que vai realmente interpretar isto. E isto significa que se o quere facer redondeo enteiro e cousas así, cómpre facer impresión (planta (10/7)); C pode ser estraño que pode confiar en truncamento enteiro regularmente, pero en PHP non pode porque el será automaticamente transformalo en un coche alegórico. E despois (7 + true), o que pensas que vai ser? Estou supoñendo que 8 se vai interpretar como unha verdadeira. Parece que é 8. Entón, calquera cousa que fixemos nos últimos 10 minutos que nunca debe facer absolutamente. Vai ver o código que fai iso. Ela non ten que ser tan sinxelo coma este. Pode ter dúas variables, e unha variable pasa a ser unha cadea e outra variable pasa a ser un int, e despois de engadir estas variables xuntas. Dende o PHP é tipada dinamicamente e non vai facer calquera tipo de verificación para ti e unha vez que é feblemente tipada e xa que só ha automaticamente xogar esas cousas xuntos e todo vai funcionar, é difícil incluso saber que esta variable debe ser unha secuencia de agora, por iso non debe engadir a esta variable, que é un enteiro. A mellor práctica é unha variable é unha cadea, mantelo como unha cadea para sempre. Se a variable é un int, mantelo como un int para sempre. Se queres tratar con números enteiros e cadeas, pode usar varsint - que é JavaScript. Intval. Fago iso o tempo. PHP e JavaScript eu misturo todo. Entón intval vai voltar o valor enteiro dunha variable. Se pasar "print (intval ('123 ')), comeza 123. Intval si só non vai facer o cheque para nós que é exclusivamente un enteiro. O manual de PHP, hai só funcións tantas dispoñible, entón aquí eu creo que o que eu usaría é is_numeric primeiro. Estou supoñendo que retornou falso. Isto é outra cousa que temos que pasar por riba é. === Entón is_numeric ('123df '), non pensaría que, como is_numeric. C, que tería que iterar sobre todos os personaxes e comprobar a ver se cada personaxe é o díxito ou o que quere. Aquí is_numeric vai facer por nós, e está retornando falso. Entón, cando eu impresa, é impreso nada, entón aquí estou comparando-a ver, Se ocorrer de lle ser falsa? E agora está imprimindo un. Ao parecer, el imprime un como verdadeiro en vez de imprimir certo como certo. Quere saber se podo facer print_r. Non, el aínda fai un. Volvendo ao ===, == aínda existe, e falar con Tommy vai dicir == é perfectamente ben. Eu vou dicir que == é terrible e nunca debe usar. == A diferenza é que as cousas == compara onde pode ser certo aínda que eles non son do mesmo tipo, Considerando === compara cousas e primeiro, comprobar son eles mesmo tipo? Si Ok, agora eu vou ver se realmente comparar a ser igual. Comeza cousas estrañas como 10 é igual a - imos ver o que di. Entón ('10 '== '1 E1'); Isto amosa certo. Alguén ten algún palpite que este retorna verdade? Non é só sobre iso. Quizais esta sexa unha información. Pero se eu cambiar isto para un f - Droga! Eu sigo usando comiñas dobres. A razón das aspas están gritando comigo é porque eu coloque iso comiñas. Entón, eu podería escapar as comiñas aquí, pero aspas facelo máis fácil. Entón ('10 '== '1 F1'); non imprime verdade. ('10 '== '1 E1'); imprime verdade. [Estudante] É Hex? >> Non é Hex, pero está preto que é como - Notación, 1e1 científica. El recoñece como 1e1 1 * 10 ^ 1, ou o que sexa. Estes son números enteiros iguais. Se facemos === entón vai ser falsa. Eu realmente non teño idea se nós facemos o que dicir == (10 e '10abc ');? Todo ben. Entón, iso é verdade. Así como cando fixo (10 + '10abc '), e que sería 20, aquí (10 == '10abc '); é certo. Peor aínda son cousas como (falsa == NULL); é verdade ou (falso == 0); é certa, (falso == []); Hai casos estraños de - Isto é un deses casos estraños. Teña en conta que (false == []); é verdade. ('0 '== False); é verdade. ('0 '== []); É falso. Entón == non é de forma transitiva. pode ser igual a un b pode ser igual a C, pero b pode non ser igual a c. Iso é unha abominação para min, e ten que usar. === [Alumno] Podemos facer! == Tamén? >> [Bowden] Si O equivalente sería! = E! ==. Isto é, en realidade, trouxo na especificación pset onde unha morea de retorno funcións - O manual de PHP é bo sobre iso. Ela coloca nunha gran caixa vermella "Isto pode voltar falso se non hai un erro." Pero volvendo 0 é unha cousa perfectamente razoable para volver. Debería calquera función que se espera para voltar un enteiro. Imos dicir que esta función debe contar o número de liñas nun arquivo ou algo así. En circunstancias normais, pasa esta función dun ficheiro e que vai voltar un enteiro que representa o número de liñas. Entón, 0 é un número perfectamente razoable o arquivo é só baleiro. Pero o que se pasar un arquivo válido ea función pasa a retornar falso se pasar un arquivo válido? Se acaba de facer == non está diferenciando o caso entre ficheiro válido e arquivo baleiro. Usar sempre. === Isto é todo isto. No PHP, tipo de matriz é diferente do que está afeito en C. En realidade, xa debe ter notado esta por riba de cando viu que este é o tipo Array. A sintaxe soporte é novo no PHP 5.4, que é a máis nova versión do PHP. Antes isto, sempre que escribir array ('a' -> 1, 'b' -> 2. Ese foi o constructor para unha matriz. Agora PHP finalmente chegou preto para ver a sintaxe agradable de só corchetes, que é só moito mellor array. Pero, considerando o PHP 5.4 é a versión máis recente, podes atopar sitios que non teñen sequera PHP 5.3. Durante o verán, corre para este problema en PHP 5.3 era o que tiñamos no aparello, pero o servidor que implantado todo o libro o noso grao e enviar todas as cousas que a era PHP 5.4. Non sabendo diso, realizamos en 5,3, empurrou para 5,4, e agora, de súpeto ningún do noso código funciona porque non pasou ser cambios entre 5,3 e 5,4 que non son compatibles, e nós temos que ir e corrixir todas as nosas cousas que non funcionan para PHP 5.4. Para esta clase, xa que o aparello ten PHP 5.4, é perfectamente posible usar corchetes. Pero se está mirando para as cousas ao redor de Internet, Se está a buscar algún tipo de material matriz, o máis probable é que vai ver o feitizo fóra sintaxe constructor de matriz dende que existe desde o PHP naceu e sintaxe de corchetes ten sido en torno dos últimos dous meses ou sempre que 5,4 veu ao redor. Isto é como índice de ti. Así como en C como se fose o índice por corchetes como $ array [0] array $ [1], array $ [2] vostede índice da mesma forma ocorrer de ter os seus índices sendo cordas. Matriz para array $ ['a'] e $ ['b']. $ Array [b]. Por que iso sería malo? El probablemente ha xerar un aviso, pero aínda funciona. PHP tende a facelo. Ela tende a só: "Eu estou indo a aviso-lo sobre iso, pero eu só vou seguir "E facer o que eu poida." El probablemente ha traducir isto para unha cadea, , Pero é posible que, nalgún momento no pasado alguén dixo definir b ser 'Ola Mundo ". Entón, agora b podería ser unha constante de matriz e US $ [b] vai ser realmente facendo "Ola Mundo". Eu creo que neste momento, ou polo menos as nosas opcións PHP, se tentar índice nunha matriz e esa clave non existe, el ha falla. Eu non creo que iso só vai te avisar. Ou polo menos, pode configuralo para que non só sinalando-lo, só en liña recta ata fallar. A xeito no que comprobar a ver se hai realmente un tal contido é isset. Entón isset ($ array ['Ola Mundo']) retornará falso. isset ($ array ['b']) volverá true. Pode mesturar estas sintaxe. Estou seguro de que esa matriz acabaría sendo é - Podemos probalo. Oh, eu teño PHPWord. Este é mesturar a sintaxe onde se especifica que é a clave e non especificar o que está a clave. Entón 3 aquí é un valor. Non dixo explicitamente que a súa clave é que vai ser. ¿Que pensas da súa clave vai ser? [Estudante] 0. >> Estou supoñendo 0 só porque é o primeiro que non especificou. Podemos realmente facer un par deses casos. Entón print_r e imprimir recursiva. El ha imprimir toda a matriz. Sería imprimir subarrays da matriz, se houbese algún. Entón print_r ($ array); php.test.php. El se parece con el deu 0. En realidade, hai algo a ter en conta aquí, pero imos volver a el en un segundo. Pero o que se ocorrer de eu facer este índice 1? PHP non fai diferenza entre os índices de cordas e índices enteiros, por iso neste momento teño só definido un índice 1 e podo facer tanto a matriz $ [1] e $ array ['1 '] e será o mesmo índice e a mesma clave. Entón agora o que pensas 3 vai ser? >> [Alumno] 2. >> [Bowden] Estou supoñendo 2. Si E 2. O que se fixésemos iso é 10, e 4? ¿Que pensas que o índice de 3 vai ser? Estou pensando 11. O meu palpite sobre o que o PHP fai - e eu creo que xa vin iso antes - É só se mantén informado do que o maior índice numérico que se usa ata agora é. Iso nunca vai asignar un índice de secuencia para 3. Será sempre un índice numérico. Por iso, mantén o control do máis alto é asignado ata agora, que pasa a ser 10, e vai dar 11-3. O que eu dixen antes, observe a forma como está a imprimir esa matriz. Ela imprime 10, tecla 4, clave 11, clave d. Ou mesmo imos facer - Coido que eu non coloque a 0, pero é a impresión 1, 2, 3, 4. E se eu cambiar aquí? Ou imos realmente cambiar estes 2. Agora que imprime 2, 1, 3, 4. Matrices de PHP non son como a súa táboa estándar de hash. É perfectamente razoable pensar neles como táboas de hash do 99% do tempo. Pero nas súas táboas de hash non hai sentido da orde en que as cousas estaban inseridos. Así, logo que inserir na táboa hash, asumir que non hai lista de ligazóns e pode xulgar dentro dunha lista ligada a cal foi inserida en primeiro lugar. Pero aquí estamos inseridos dous primeiro e sabe cando e imprimir esa matriz que 2 ven en primeiro lugar. Non imprimir lo en só un fin calquera. A estrutura de datos técnicos que está a usar é un mapa ordenado, así que mapea claves para valores e recorda a orde en que as claves foron inseridas. Basicamente é para algunhas complicacións en que é aburrido para realmente - Imos dicir que ten unha matriz 0, 1, 2, 3, 4, 5 e quere aproveitar índice 2. Unha forma de facelo, imos ver o que parece. 0, 2, 1, 3, 4. Unset acontece para eliminar as dúas variables e índices da matriz. Entón unset ($ array [2]); Agora, o que iso vai parecer? 2 é só ir aínda que, de modo que é perfectamente ben. Máis irritante é se quere que as cousas realmente como unha matriz. Vou poñer números aleatorios. Agora, observe os meus índices. Eu quero que sexa só como unha matriz C, onde vai de 0 a duración - 1 e podo iterar sobre el como tal. Pero así que eu eliminar o segundo índice, que estaba no índice 3 non agora se fixo índice 2. En vez diso, só elimina ese índice e agora vai de 0, 1, 3, 4. Isto é perfectamente razoable. É só irritante e ten que facer cousas como emenda matriz. Si [Alumno] O que sucedería se tivese un loop e quería pasar por riba de todos os elementos? Cando bateu dous, sería renderse sempre? Iteração sobre unha matriz. Hai dúas formas de facelo. Podes usar un estándar para loop. Esta é outra complexidade do PHP. A maioría das linguaxes, eu diría, teñen algún tipo de lonxitude ou len ou algo indica a lonxitude dunha matriz. O PHP é contar. Entón count ($ array); $ i + +) Nós só impresión ($ array [$ i]); Aviso: Undefined offset: 2. El só vai fallar. Esta é a razón que para a maior parte, nunca debe iterar sobre unha matriz coma este. Pode ser unha esaxeración, pero nunca debe iterar sobre unha matriz como esta porque o PHP ofrece a súa sintaxe foreach onde foreach (array $ como $ elemento). Agora, se nós imprimir ($ item); - nós discutir iso nun segundo - que funciona perfectamente ben. O xeito que foreach está a traballar é o primeiro argumento é a matriz que está iterando. E o segundo argumento, elemento, a través de cada paso do loop que vai asumir a seguinte cousa na matriz. Entón lembre-se a matriz ten unha orde. A primeira vez a través do loop for, o elemento será 123 , El ha ser de 12, a continuación, será de 13, el ha ser de 23, entón será 213. As cousas están realmente estraño cando fai algo así como foreach. Imos ver o que pasa, porque nunca debe facelo. E se nós unset ($ array [1]); Que probablemente foi o esperado. Vostede está interactuando sobre esta matriz, e cada vez que está desconfigurar o primeiro índice. Entón, para o índice 0, o primeiro elemento, asume valor 0, polo que vai ser 123. Pero dentro do loop que unset Índice 1, o que significa 12 está desaparecido. Así imprimir. PHP_EOL. PHP_EOL é só de nova liña, pero é tecnicamente máis portátil dende novas liñas en Windows é diferente de novas liñas en Mac e Unix. En Windows nova liña é \ r \ n, mentres que en calquera outro lugar que tende só para ser \ n. PHP_EOL está configurado para que el usa o que quere que a nova liña do seu sistema. Así que imprimir. Non imos print_r ($ array) ao final. Eu non tiña idea de que iso sería o comportamento. Elemento aínda asume o valor de 12 aínda que unset 12 antes de nós sempre para el a partir da matriz. Non Tomé miña palabra sobre iso, pero parece que foreach crea unha copia da matriz e entón o elemento asume todos os valores que a copia. Así, mesmo se cambiar a matriz dentro do loop for, non vai se importar. Elemento será asumir os valores orixinais. Imos tentar desarmar-lo. E este é de R $ array [1] = "Ola"; Mesmo que poñer "Ola" para a matriz, nunca elemento leva ese valor. Hai outra sintaxe para foreach lazos onde poñer dúas variables separadas por unha frecha. Esta primeira variable será a clave deste valor, e esta segunda variable será o mesmo elemento exacto. Isto non é interesante aquí, pero se volvemos ao noso caso orixinal de 'a' -> 1, 'B' -> 1, aquí só iterar para cada matriz como elemento, o elemento será unha cada vez. Pero se nós tamén queremos saber a clave asociada con este elemento despois facemos as $ clave -> elemento $. Entón agora podemos facer impresión (tecla $. ':'. Agora está iterando e impresión de cada clave eo seu valor asociado. Unha cousa adicional que podemos facer en foreach loops é que pode ver esta sintaxe. E comercial antes de nomes de variables tenden a ser como o PHP fai referencias. Onde as referencias son moi semellantes aos punteiros, non ten punteiros, entón non xestione a memoria directamente. Pero ten referencias onde unha variable refírese a mesma cousa que outra variable. Aquí dentro, imos facer $ elemento. Imos volver 1, 10. Imos facer $ item + +; que aínda existe en PHP. Aínda pode facer + +. php.test.php. Eu teño que imprimir lo. print_r ($ array); Nós imprimir 2, 11. Se eu tivese feito foreach (array $ como $ item) entón o elemento será o valor 1 por primeira vez a través do loop. El ha incrementar 1-2 e despois estamos a facer. Entón vai pasar a segunda pasaxe do lazo e ese elemento é de 10. É elemento de incrementos a 11, e despois que acabou xogado fóra. Entón nós print_r ($ array), e imos ver o que este é só un de 10. Así, o incremento que fixemos foi perdido. Pero foreach (array $ a & $ item) agora este elemento é o mesmo elemento como este aquí. É a mesma cousa. Entón elemento de R $ + + está modificando matriz 0. Basicamente, vostede tamén pode facer $ k -> array $ elemento e pode facer [$ k] + +; Así, outra forma de facelo, somos libres para modificar elemento, pero iso non vai cambiar a nosa matriz orixinal. Pero se usamos k, que é a nosa clave, entón podemos só o índice na nosa matriz usando a clave e incrementar iso. Esta máis directamente modifica nosa matriz orixinal. Pode até facelo por algún motivo quere que a capacidade de modificar - En realidade, iso é perfectamente razoable. Non quería ter que escribir $ array [$ k] + +, só quería escribir $ item + +, pero aínda quería dicir if ($ k === 'a') entón incrementar elemento e, a continuación, imprimir a nosa matriz. Entón agora o que esperamos print_r facer? Que valores deben ser impresos? [Estudante] 2 e 10. >> [Bowden] Só a clave era 'a' nós realmente imprimir iso. Vostede, probablemente, moi raramente, ou nunca, será necesario definir funcións en PHP, pero podes ver algo semellante, onde define unha función como calquera función. Normalmente diría ($ foo $ bar) e, entón, establecer que sexa o que sexa. Pero se eu fai iso, entón iso significa que o que chama de calquera cousa, calquera que chama Baz, de xeito que o primeiro argumento pasado para Baz pode ser cambiado. Imos facer $ foo + +; e aquí dentro, imos facer Baz ($ item); Agora estamos chamando unha función. O argumento é tomado por referencia, o que significa que, se modificalo lo estamos modificando a cousa que foi pasado dentro E a impresión dese esperamos - a menos que eu errei sintaxe - temos 2, 11, así foi, en realidade, incrementado. Teña en conta que cómpre referencias en dous lugares. E se eu fixen iso? O que significa isto? [Alumno] vai cambiar. Si >>. Elemento é só unha copia do valor na matriz. Así, o artigo ha cambiar a 2, pero a matriz ['a'] aínda será 1. Ou o que se eu fai iso? Agora elemento é enviado como copia de Baz. Polo tanto, a copia do argumento será incrementado a 2, pero o elemento en si nunca foi incrementado a 2. E elemento é o mesmo que o soporte de matriz que sexa, de xeito que a matriz nunca foi incrementado. Así, ambos os lugares precisan. PHP é xeralmente moi intelixente sobre iso. Podes pensar que quero pasar por referencia - Esta foi realmente unha pregunta sobre unha das serie de exercicios. Foi unha cousa questions.txt onde di: Por que quere pasar esa estrutura por referencia? Cal foi a resposta? [Alumno] Entón non tes que copiar algo grande. Si >>. Unha estrutura pode ser arbitrariamente grande, e cando pasar a estrutura como un argumento precisa copiar a estrutura enteira para pasalo para a función, mentres que se só pasar a estrutura por referencia entón só precisa copiar un enderezo de 4 bytes como argumento para a función. PHP é un pouco máis intelixente do que iso. Se ten algunha función e eu pasar a el unha serie de cousas 1000, Isto significa que vai ter que copiar todo 1.000 destas cousas para pasar á función? Non ten que facer iso inmediatamente. Dentro desta función nunca realmente modifica foo, por iso, se ($ foo === 'Ola') return true.; Teña en conta que de feito nunca modificou o interior argumento desta función, o que significa que todo o que foi pasado como nunca foo precisa ser copiado porque non é modificalo. Así, a modo PHP obras e os argumentos son sempre pasados ​​por referencia ata que realmente tentar modificalo. Agora, se eu digo $ foo + +, que vai agora facer unha copia do foo orixinal e modificar a copia. Isto aforrar moito tempo. Se nunca está tocando esta enorme variedade, nunca realmente modificalo-lo, non necesita para facer a copia, mentres que se nós só poñemos ese comercial que significa que nin sequera copia-lo mesmo se modificalo. Este comportamento é chamado de copia na gravación. Vai velo noutros lugares, especialmente se aproveitar un curso de sistema operativo. Copy-on-write é un estándar bastante usual que non precisa facer unha copia de algo a menos que sexa realmente cambiando. Si [Alumno] E se tivese o incremento dentro da proba, tan só o elemento 1 de 1000 terá que ser cambiado? Non estou seguro. Coido que sería copiar a cousa toda, pero é posible que el é intelixente o suficiente para que - En realidade, o que eu estou pensando é imaxinar que tiñamos unha matriz que queda así: $ array2 = [ Entón índice de 'a' é unha matriz de [1 2 3 4], índice e 'b' é unha matriz de calquera cousa. Eu teño comas entre todos estes. Imaxina que hai dous puntos. A continuación, 'c' é o 3 valor. Okay. Agora imos dicir que temos $ Baz ($ array2); onde Baz non tomar esta referencia. Entón $ foo ['c'] + +; Este é un exemplo onde estamos pasando array2 como un argumento e en seguida, é a modificación dun índice específico da matriz, incrementando-lo. Eu honestamente non teño idea do que o PHP vai facer. Pode facilmente facer unha copia de toda a cousa, pero se é intelixente, vai facer unha copia destas chaves, onde esta terá o seu valor distinto pero esta aínda pode apuntar para o mesmo matriz 1,2,3,4 e isto pode apuntar para o mesmo matriz. Vou iPad lo. Pasamos esa matriz onde este cara puntos 3, que apunta a cara [1,2,3,4], este cara apunta a [34, ...] Agora que estamos pasando para Baz, estamos modificando iso. Se o PHP é intelixente, pode só facer - Aínda tiña que copiar algunha memoria, pero se houbese esas subarrays enormes aninhadas Nós non precisamos copiar. Eu non sei se é iso que fai, pero podo imaxinar que está facendo iso. Esta tamén é unha vantaxe moi grande de C sobre PHP. PHP fai a vida moito máis fácil para unha morea de cousas, pero medio que ten absolutamente ningunha idea de como ha executar porque eu non teño ningunha idea debaixo do capó cando se está a facer estas copias de cousas, oh, é que vai ser unha copia de tempo constante, É só vai cambiar un punteiro, que vai ser unha copia ridiculamente difícil lineal? E se non pode atopar espazo? Será que precisa entón para realizar a recolección de lixo para conseguir espazo un pouco máis? E recolección de lixo pode tomar arbitrariamente longo. C non ten que se preocupar con estas cousas. Cada liña que escribe pode razoar moi bonita sobre como vai realizar. Imos mirar para estes. Que bo é que non tes que tratar con funcións de hash, listas ligadas, ou algo así? Desde que traballo con táboas de hash é tan fácil agora, aquí está un puzzle divertido para traballar. Abrir un ficheiro chamado unique.php e nela escribir un programa PHP (Tamén coñecido como un "guión"). Nós tendemos a chamalos de guións se son cousas pequenas que executa na liña de comandos. Basicamente, calquera linguaxe que non compilar, pero está indo a executar o arquivo executábel na liña de comandos, pode chamar este script executable. Eu podería moi ben escribir un programa en C que fai iso, pero eu non chamalo de un script desde que eu compilar e executar o binario. Pero este programa PHP imos chamar un script. Ou se escribiu en Python ou Perl ou Node.js ou calquera destas cousas, nós chama-los de todos os scripts porque executa-los na liña de comandos pero non recompila-los. Nós poderiamos facelo moi rapidamente. Nós non estamos indo a usar argv. Nós só explotar por iso. Chama-o único, escribir un programa. Pode asumir que a entrada contén unha palabra por liña. En realidade, argv será ben sinxelo de usar. unique.php. Primeiro de todo, queremos comprobar se foron pasados ​​un argumento de liña de comandos. Así como sería de esperar argc e argv en C, aínda temos os en PHP. Entón, se ($ argc! == 2) entón eu non vou tratar con a impresión dunha mensaxe ou calquera cousa. Eu só vou saír, código de erro de 1. Eu tamén podería volver 1. Raramente en PHP está neste estado onde estamos - Normalmente, está en unha función chamada por unha función chamada por unha función chamada por unha función. E se algo sae mal e só quere saír todo enteiramente, saída só encerra o programa. Isto tamén existe en C. Se vostede está en unha función dunha función nunha función en función e quere só matar o programa, pode chamar de saída e vai saír. Pero en PHP é aínda máis raro que estamos neste nivel superior. Normalmente estamos dentro dalgún tipo de función, por iso chamamos de saída de xeito que non temos que volver a unha cousa que, entón, entende que hai un erro así que retorna si recoñece que houbo un erro. Non queren tratar con isto, entón saír (1); retorno (1), neste caso, sería equivalente. Entón, o que queremos abrir queremos fopen. Os argumentos van ollar moi semellantes. Queremos fopen ($ argv [1], e queremos abrilo para a súa lectura. Que retorna un recurso que nós imos chamar f. Isto parece moi semellante á forma como C fai iso, agás que non temos que dicir * File. En vez diso, só dicir $ f. Okay. En realidade, eu creo que iso aínda nos dá unha información de PHP función chamada arquivo. Arquivo PHP. O que é que isto vai facer é ler un ficheiro nunha matriz. Non precisa aínda de fopen-lo. El vai facelo por vostede. Entón $ liñas = file ($ argv [1]); Agora, todas as liñas do ficheiro son en liñas. Agora queremos clasificar as liñas. Como podemos clasificar as liñas? Nós clasificar as liñas. E agora podemos imprimilas los ou o que sexa. Probablemente o xeito máis doado é foreach ($ lines as $ liña) echo $ liña; [Alumno] non sería mesmo de cruzar as liñas, facendo referencia a algo en especie? Este é o lugar onde tipo pode ser definido como unha especie de función (+ $ array). Cando chama a función que non pase por referencia. É a función que define como tomalo como referencia. Este é, en realidade, exactamente o que deu mal cando poñemos todo nos nosos servidores cando fomos 5,3-5,4. Ata 5.4, iso era perfectamente razoable. Unha función non espera para levalo como referencia, pero pode pasar isto como referencia por iso, se a función non acontece para modificalo lo, aínda é modificado. A partir de 5.4, non debería facelo. Entón, agora a única forma de pasar por referencia é a función explícitamente o fai. Se non quere que para modificalo lo, entón tes que facer copy = $ $ liñas e copia pase. Entón, agora as liñas serán preservados e copia será alterado. php.unique.php. Eu podería ter sujado algo. 'Tipo' inesperado. Non vai ser algo que fai iso para nós. El non está alí. Teña en conta que cando vostede lea a guía que o primeiro argumento é expected para ser un array e é tomado por referencia. Por que isto está reclamando comigo? Porque eu teño ese tipo de función aínda aquí que eu non quero. Ok, php.unique.php. Eu non pasar un argumento, porque eu non teño un arquivo. É php.unique.php en test.php. Aquí está test.php todos impresos nunha orde legal clasificados. Teña en conta que orde de clasificación é medio raro para un arquivo de código porque todas as nosas liñas en branco van vir en primeiro lugar entón van vir todos os nosos recortes de nivel 1 despois veñen os nosos recortes non. Si >> [Alumno] Polo tanto, para o código fonte non foi pasado por referencia? É xeralmente pasados ​​por valor? [Bowden] Cando chamar unha función, nunca determina se foi pasado por referencia. É a definición da función que determina se foi pasado por referencia. E mirando para a definición da función de clasificación ou só mirando para iso, que leva o argumento por referencia. Polo tanto, independentemente de se quere tomar por referencia, toma por referencia. El modifica a matriz no lugar. Este non é só admite. Non ten permiso para facelo. >> [Alumno] Ah, ok. [Bowden] Iso, tipo vai ter liñas de referencia e modificalo. E, de novo, se non quere que faga iso, pode facer unha copia de tipo. Mesmo neste caso, a copia non é, en realidade, unha copia de liñas. El só apunta a mesma cousa, ata que primeiro é modificado, onde está primeiro vai ser modificado en función de clasificación, onde, porque é copia na gravación, agora unha copia do exemplar vai ser feita. Tamén pode facelo. Ese é o lugar que pode ver e comercial. Vostede ve isto loops foreach, ve-lo declaracións de función, e velo cando só a asignación de variables. Agora non realizamos nada, facendo iso porque copia e liñas son literalmente o mesmo. Podes empregar liñas e copiar alternativamente. Podes facer unset (copia $) e que non fai liñas unset, acaba de perder a súa referencia para o mesmo. Entón, a partir deste punto, agora liñas é a única forma que pode acceder liñas. Preguntas? Si [Alumno] Completamente fóra topic, pero non ten que pechar o PHP - >> Non. Okay. [Bowden] Eu ía tan lonxe a punto de dicir que é unha mala práctica para pecha-las. Isto é probablemente unha esaxeración, especialmente en un script, pero imos ver o que acontece se eu facer iso. Que non fixo nada. E se eu quería - [suspira] Eu teño pasar un argumento. Shoot. Eu chamei o mal. Entón php.unique.php cun argumento. Agora eu non teño diso. Vou pasar para el un argumento válido. Este impreso o que é impresión. Eu estou imprimindo copia e copia non existe. Así liñas. É impreso todo, e entón entender todo ese lixo aquí, porque en nada PHP que está fóra das etiquetas PHP é só ir a ser impreso literalmente. É por iso que o HTML, é tan bo que podo facer div bla, bla, bla de clase ou o que sexa, bla, bla, bla e despois facer un código PHP e despois facer div final. E agora a impresión que eu recibín a miña div agradable enriba, o único que o PHP impreso, div na parte inferior. Desastroso cando algo así pasa, o que é bastante común, só unha nova liña perdida no fondo do arquivo. Non pensa que sería a de un gran negocio ata considerar o feito de que con navegadores - Como redirecciona traballo ou, basicamente, a obra de cabeceira, cando fai a súa conexión a un sitio web e envía de volta todos estes cabezallos e cousas como resposta 200 ou resposta redireccionar ou o que sexa, cabeceiras son válidos só ata o primeiro byte de datos é enviado. Pode redirixir miles de veces, pero, logo que o primeiro byte de datos é enviado non debería redireccionar novo. Se ten unha nova liña fixa na parte inferior dun ficheiro e digamos que use esa función e entón quere - Imos dicir que é outro arquivo que é index.php e require_once algo - Eu non podo pensar en un bo exemplo diso. O problema ocorre cando esta liña na parte inferior está eco. Non quere nada ser ecoado aínda. Aínda que non tiña a intención de quedar eco nada, algo que se repetiu e agora non debe enviar cabeceiras máis ningunha e está indo para obter queixas. Só non precisa desas etiquetas de peche. Se está a pensar en facer algo con HTML - e é perfectamente razoable a facer aquí o que div e entón, neste punto pode ou non pode inclui-los. Isto realmente non importa. Pero en scripts PHP é raro para a pechar. Cando todo está PHP, absolutamente todo, realmente non precisa pechalo / non debe pechalo. Tratar con cordas é moito máis agradable do que en C. No PHP, pode especificar unha cadea con comiñas simples ou dobres. Con aspas simples non pode usar "escape" secuencias. Constantemente escapar, bla, bla, bla. Entón printf é moi raro en PHP. Eu creo que eu ía usar printf se eu quería facer un tipo de cousas - que usou pset 5 sprintf ou o que quere. Pero quere facer 001.jpg 002.jpg e. Así, para este tipo de cousas que eu realmente quero formatar o texto que eu ía usar printf. Pero se non, eu ía usar só concatenação. Eu nunca realmente usar printf. Estamos só diferenciar os detalles entre comiñas simples e comiñas dobres. A maior diferenza é que comiñas simples, el será impreso literalmente. Non hai ningún tipo de datos char en PHP, ao contrario de C, de modo que este é equivalente a este. Son dúas cordas. E a cousa agradable sobre cordas aspas é que eu podería dicir 'Ola Mundo! " bla, bla, bla, $ $ Wooo. O que acontece cando imprimir esta é que vai imprimir lo literalmente. Imos nos librar de todas as nosas cousas. Entón echo $ str1; É, literalmente, impreso todas estas cousas: signos de dólar, barra invertida n, cal pensas que sería newlines - todas estas cousas que imprime literalmente. O único que necesitas escapar son aspas porque se non, podería pensar que está pechando as comiñas simples. Comiñas, completamente diferentes. Xa vemos o destaque da sintaxe é cluing connosco para o que está a piques de ir terrible mal. php.unique. Indefinido variable: wooo porque esta é interpretada como unha variable chamada wooo. Comiñas dobres permiten que introducir variables - Digamos $ name = "Rob"; Entón echo "Hola, meu nome é $ nome"; Ela recoñece esta como unha variable. Cando executo iso - e vou introducir unha nova liña - Ola, meu nome é Rob! e Ola mundo! Isto é porque nunca tirei a impresión de wooo anterior. Hai un paso máis que se pode facer. $ Array = [1, 2, 3]; E se eu queira imprimir o primeiro índice de matriz? Fai $ array [0]. O realce de sintaxe é unha pista. O que é que isto vai facer? php.unique. Ola, meu nome é 1! o que non é o que eu quería. O destaque da sintaxe mentiu para min. Imos tentar 'a' -> 1, 'b' -> 2. É así que eu tería que escribir. Comiñas simples inesperado (T_ENCAPSED bla, bla, bla, bla, bla). A idea é a de que non está recoñecendo isto como parte da matriz. Non está recoñecendo isto como matriz indexadas por unha carta. Quere facelo rodeado por chaves, e agora o que está neste chaveta serán interpoladas, que é a palabra que usamos para Magic inserción destas variables para os lugares certos. Agora facelo, php.unique, e Ola, meu nome é 1! como esperaba ou Ola, meu nome é Rob! Unha cousa que é unha especie de bo sobre aspas que - Hai algún custo para interpolación. Se usar comiñas dobres, o intérprete ten que pasar por riba esta secuencia, asegurarse de que, "Oh, aquí está unha variable. Agora eu teño ir buscar esa variable e inserir-lo aquí." Mesmo se non usar todas as variables, nada dentro destas aspas que ser interpolados, pero aínda vai ser máis lento porque necesita pasar por riba das aspas á procura de cousas que precisan ser interpolados. Entón citas individuais poden ser un pouco máis rápido se non ten que ser interpolados, e eu aínda tenden a usar comiñas simples para "Ola, meu nome é '. $ Array ['a'] de calquera maneira. Isto vai ser equivalente ao que tiñamos antes. Pero é unha cuestión de preferencia. Se está usando PHP, probablemente non lle importa a diferenza de velocidade. Non é o suficiente para razoar los para comezar. Todas as preguntas finais? En realidade, nin sequera pasar por todo iso, pero este material era aburrido. A última cousa que é unha especie de bo no PHP é cando está lidando con HTML, vai usalo un pouco, entón a sintaxe bo atallo para a impresión dunha variable. Sen poñer PHP aquí, iso é chamado de etiquetas curtas. Oficialmente a partir do PHP 5.4, que é depreciada. Recoméndase colocar php. Este aínda é soportado, etiquetas para curtas con